Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rf308cc4c35eab630ebbbde405cfe47d049afeafb -r94a190522ce398399c7b93c59f788d7666ec0060 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision f308cc4c35eab630ebbbde405cfe47d049afeafb) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) @@ -1,22 +1,26 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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 +* @file AlarmMgmt.c * -* @author (last) Quang Nguyen -* @date (last) 22-Jul-2020 +* @author (last) Quang Nguyen +* @date (last) 19-Jul-2021 * -* @author (original) Sean -* @date (original) 04-Feb-2020 +* @author (original) Sean +* @date (original) 04-Feb-2020 * ***************************************************************************/ + +#define __ALARM_MGMT_C__ #include "AlarmMgmt.h" -#include "OperationModes.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "SystemComm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -27,62 +31,60 @@ */ // ********** private definitions ********** + +// *** This declaration will cause a compiler error if ALARM_TABLE does not have same # of alarms as the Alarm_List enumeration. +U08 alarmTableSizeAssertion[ ( ( sizeof( ALARM_TABLE ) / sizeof( ALARM_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; + +// *** This declaration will cause a compiler error if ALARM_RANK_TABLE does not have same # of alarms as the Alarm_List enumeration. +U08 alarmRankTableSizeAssertion[ ( ( sizeof( ALARM_RANK_TABLE ) / sizeof( ALARM_RANK_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; -/// A blank alarm data record for alarms that do not include alarm data when triggered. -const ALARM_DATA_T blankAlarmData = { ALARM_DATA_TYPE_NONE, 0 }; +const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; ///< A blank alarm data record for alarms that do not include alarm data when triggered. // ********** private data ********** + +static BOOL 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 -/// table - current state of each alarm -DATA_ARRAY_DECL( BOOL, AlarmStates, NUM_OF_ALARM_IDS, alarmIsActive ); - // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); -static DATA_ARRAY_GET_PROTOTYPE( BOOL, getAlarmActive, alarmID ); -/************************************************************************* - * @brief initAlarmMgmt +/*********************************************************************//** + * @brief * The initAlarmMgmt function initializes the AlarmMgmt module. - * @details - * Inputs : none - * Outputs : AlarmMgmt module initialized. + * @details Inputs: none + * @details Outputs: AlarmMgmt module initialized. * @return none *************************************************************************/ void initAlarmMgmt( void ) { - ALARM_ID_T a; + ALARM_ID_T alrm; // initialize alarm states and start time stamps - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + for ( alrm = ALARM_ID_NO_ALARM; alrm < NUM_OF_ALARM_IDS; alrm++ ) { - alarmIsActive[ a ].data = FALSE; - alarmIsActive[ a ].ovData = FALSE; - alarmIsActive[ a ].ovInitData = TRUE; - alarmIsActive[ a ].override = OVERRIDE_RESET; + alarmIsActive[ alrm ] = FALSE; + alarmConditionIsActive[ alrm ] = FALSE; } } - -/************************************************************************* - * @brief execAlarmMgmt - * The execAlarmMgmt function executes the alarm management functions to be \n - * done periodically. - * @details - * Inputs : - * Outputs : + +/*********************************************************************//** + * @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 activateAlarm + +/*********************************************************************//** + * @brief * The activateAlarm function activates a given alarm. - * @details - * Inputs : none - * Outputs : alarmIsActive[] + * @details Inputs: none + * @details Outputs: alarmIsActive[] * @param alarm ID of alarm to activate * @return none *************************************************************************/ @@ -92,128 +94,88 @@ if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { // no need to do anything if alarm is already active - if ( FALSE == getAlarmActive( alarm ) ) + if ( FALSE == alarmIsActive[ alarm ] ) { // activate alarm - alarmIsActive[ alarm ].data = TRUE; + alarmIsActive[ alarm ] = TRUE; + alarmConditionIsActive[ alarm ] = TRUE; + + // If alarm is a DG fault, request transition to fault mode + if ( TRUE == ALARM_TABLE[ alarm ].alarmIsDGFault ) + { + requestNewOperationMode( DG_MODE_FAUL ); + } + // If alarm has clear condition immediately property, clear condition now + if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) + { + clearAlarmCondition( alarm ); + } } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) } } - -/************************************************************************* - * @brief activateAlarmNoData - * The activateAlarmNoData function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n - * include given data in the broadcast message for logging. - * @details - * Inputs : none - * Outputs : alarm triggered message sent, alarm activated + +/*********************************************************************//** + * @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 - * @param alarmData supporting data to include in alarm msg * @return none *************************************************************************/ void activateAlarmNoData( ALARM_ID_T alarm ) -{ - // broadcast alarm and data if alarm not already active - if ( FALSE == alarmIsActive[ alarm ].data ) - { - broadcastAlarmTriggered( (U16)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 ); +{ + activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA ); } - -/************************************************************************* - * @brief activateAlarm1Data - * The activateAlarm1Data function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n - * include given data in the broadcast message for logging. - * @details - * Inputs : none - * Outputs : alarm triggered message sent, alarm activated + +/*********************************************************************//** + * @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 msg + * @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( (U16)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 ); +{ + activateAlarm2Data( alarm, alarmData, BLANK_ALARM_DATA ); } - -/************************************************************************* - * @brief activateAlarm2Data - * The activateAlarm2Data function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n - * include two given data in the broadcast message for logging. - * @details - * Inputs : none - * Outputs : alarm triggered message sent, alarm activated + +/*********************************************************************//** + * @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 msg - * @param alarmData2 supporting data to include in alarm msg + * @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 ) + if ( ( FALSE == alarmIsActive[ alarm ] ) && ( TRUE == isHDCommunicating() ) ) { - broadcastAlarmTriggered( (U16)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 + broadcastAlarmTriggered( alarm, alarmData1, alarmData2 ); } - activateAlarm( alarm ); } - -/************************************************************************* - * @brief clearAlarm - * The clearAlarm function clears a given alarm if it is recoverable. Also \n - * an alarm message is broadcast to the rest of the system. - * @details - * Inputs : none - * Outputs : AlarmStatusTable[] + +/*********************************************************************//** + * @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 *************************************************************************/ @@ -223,71 +185,102 @@ 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; -#ifdef DEBUG_ENABLED -#ifdef ALARMS_DEBUG + if ( TRUE == alarmIsActive[ alarm ] ) + { + if ( TRUE == isHDCommunicating() ) { - // TODO - temporary debug code - remove later - char debugStr[ 256 ]; - sprintf( debugStr, "ALARM cleared:%5d \n", alarm ); - sendDebugData( (U08*)debugStr, strlen(debugStr) ); - sendDebugDataToUI( (U08*)debugStr ); + broadcastAlarmCleared( alarm ); } -#endif -#endif + alarmIsActive[ alarm ] = FALSE; + clearAlarmCondition( alarm ); } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, alarm ) } } - -/************************************************************************* - * @brief isAlarmActive - * The isAlarmActive function determines whether a given alarm is currently \n - * active. - * @details - * Inputs : alarmIsActive[] - * Outputs : none - * @param alarmID ID of alarm to check + +/*********************************************************************//** + * @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 ] ) + { + if ( TRUE == isHDCommunicating() ) + { + 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 = getAlarmActive( alarm ); - - return result; + return alarmIsActive[ alarm ]; } + +/*********************************************************************//** + * @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 ); + } +} + /************************************************************************* - * @brief getAlarmActive - * The getAlarmActive function gets the active state of a given alarm. - * @details - * Inputs : alarmIsActive[] - * Outputs : none - * @param alarmID ID of alarm to check - * @return TRUE if given alarm is active, FALSE if not - *************************************************************************/ -static DATA_ARRAY_GET( BOOL, getAlarmActive, alarmID, NUM_OF_ALARM_IDS-1, alarmIsActive, TRUE ) - - -/************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - - -/************************************************************************* + + +/*********************************************************************//** * @brief - * The testSetAlarmStateOverride function overrides the state of the \n - * alarm active state for a given alarm with the alarm management with \n - * a given active state. - * @details - * Inputs : none - * Outputs : alarm activated or cleared + * 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 @@ -300,7 +293,7 @@ { if ( TRUE == isTestingActivated() ) { - if ( TRUE == state ) + if ( TRUE == (BOOL)state ) { activateAlarmNoData( (ALARM_ID_T)alarmID ); } @@ -314,14 +307,13 @@ return result; } - -/************************************************************************* + +/*********************************************************************//** * @brief - * The testResetAlarmStateOverride function resets the override of the \n + * The testResetAlarmStateOverride function resets the override of the * state of the active state for a given alarm with the alarm management. - * @details - * Inputs : none - * Outputs : alarm cleared + * @details Inputs: none + * @details Outputs: alarm cleared * @param alarmID ID of alarm to clear * @return TRUE if alarm clear successful, FALSE if not *************************************************************************/