Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r2505e43eaab426e0de49f67ebb9b78efcfd13f55 -r94a190522ce398399c7b93c59f788d7666ec0060 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 2505e43eaab426e0de49f67ebb9b78efcfd13f55) +++ 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) Sean Nash -* @date (last) 19-Aug-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,46 +31,48 @@ */ // ********** 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 ) ]; -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. +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 OVERRIDE_U32_T alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of current state of each alarm +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 // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); -static BOOL getAlarmActive( U32 alarmID ); /*********************************************************************//** * @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 * The execAlarmMgmt function executes the alarm management module. - * @details - * Inputs : none - * Outputs : none + * @details Inputs: none + * @details Outputs: none * @return none *************************************************************************/ void execAlarmMgmt( void ) @@ -77,9 +83,8 @@ /*********************************************************************//** * @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 *************************************************************************/ @@ -89,10 +94,22 @@ 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 @@ -105,76 +122,39 @@ * @brief * The activateAlarmNoData function activates a given alarm. An alarm message * is broadcast to the rest of the system. - * @details - * Inputs : none - * Outputs : alarm triggered message sent, alarm activated + * @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( (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 * 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 - * Outputs : alarm triggered message sent, alarm activated + * @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( (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 * 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 - * Outputs : alarm triggered message sent, alarm activated + * @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 @@ -183,32 +163,19 @@ 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 * 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 - * Outputs : AlarmStatusTable[] + * @details Inputs: none + * @details Outputs: AlarmStatusTable[] * @param alarm ID of alarm to clear * @return none *************************************************************************/ @@ -218,21 +185,14 @@ 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 @@ -241,53 +201,74 @@ } } +/*********************************************************************//** + * @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[] - * Outputs : none - * @param alarmID ID of alarm to check + * @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 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 BOOL getAlarmActive( U32 alarmID ) +/*********************************************************************//** + * @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 ) { - BOOL result = TRUE; - if ( alarmID < NUM_OF_ALARM_IDS ) + if ( TRUE == isPersistentAlarmTriggered( alarm, isErrorOccured ) ) { - if ( OVERRIDE_KEY == alarmIsActive[ alarmID ].override ) - { - result = (BOOL)alarmIsActive[ alarmID ].ovData; - } - else - { - result = (BOOL)alarmIsActive[ alarmID ].data; - } + SET_ALARM_WITH_2_F32_DATA( alarm, data, limit ); } - else + + if ( TRUE == isPersistentAlarmConditionCleared( alarm, isErrorOccured ) ) { - activateAlarmNoData( ALARM_ID_DG_SOFTWARE_FAULT ); + clearAlarmCondition( alarm ); } +} - return result; -} - /************************************************************************* * TEST SUPPORT FUNCTIONS @@ -298,9 +279,8 @@ * @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 - * Outputs : alarm activated or cleared + * @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 @@ -332,9 +312,8 @@ * @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 - * 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 *************************************************************************/