Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rbb1f2d023593cbd1428c05e361745623a60ffb94 -r0f6b35ef8da4d30793a181750d0a6d5898118120 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision bb1f2d023593cbd1428c05e361745623a60ffb94) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 0f6b35ef8da4d30793a181750d0a6d5898118120) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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) 26-Aug-2020 +* @author (last) Dara Navaei +* @date (last) 26-Mar-2022 * -* @author (original) Sean -* @date (original) 04-Feb-2020 +* @author (original) Sean +* @date (original) 04-Feb-2020 * ***************************************************************************/ @@ -20,6 +20,8 @@ #include "AlarmMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" +#include "SafetyShutdown.h" +#include "SystemComm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -31,19 +33,32 @@ // ********** private definitions ********** +/// Interval (ms/task time) at which the alarm information is published on the CAN bus. +#define ALARM_INFO_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define DATA_PUBLISH_COUNTER_START_COUNT 12 ///< Data publish counter start count. + // *** 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 BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; ///< A blank alarm data record for alarms that do not include alarm data when triggered. +#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. + // ********** 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 +static U32 alarmInfoPublicationTimerCounter; ///< Used to schedule alarm information publication to CAN bus. +/// Interval (in task intervals) at which to publish alarm information to CAN bus. +static OVERRIDE_U32_T alarmInfoPublishInterval = { ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, 0 }; // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); +static void publishAlarmInfo( void ); /*********************************************************************//** * @brief @@ -54,7 +69,9 @@ *************************************************************************/ void initAlarmMgmt( void ) { - ALARM_ID_T alrm; + ALARM_ID_T alrm; + + alarmInfoPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; // initialize alarm states and start time stamps for ( alrm = ALARM_ID_NO_ALARM; alrm < NUM_OF_ALARM_IDS; alrm++ ) @@ -74,6 +91,9 @@ void execAlarmMgmt( void ) { // TODO - any alarm audio or LED/lamp management for DG? + + // Publish alarm information at interval + publishAlarmInfo(); } /*********************************************************************//** @@ -97,9 +117,14 @@ alarmConditionIsActive[ alarm ] = TRUE; // If alarm is a DG fault, request transition to fault mode - if ( TRUE == ALARM_TABLE[ alarm ].alarmIsDGFault ) + if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsDGFault ) && ( getCurrentOperationMode() != DG_MODE_SERV ) ) { requestNewOperationMode( DG_MODE_FAUL ); + } + // If alarm has clear condition immediately property, clear condition now + if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) + { + clearAlarmCondition( alarm ); } } } @@ -154,7 +179,7 @@ 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 ] ) + if ( ( FALSE == alarmIsActive[ alarm ] ) && ( TRUE == isHDCommunicating() ) ) { broadcastAlarmTriggered( alarm, alarmData1, alarmData2 ); } @@ -177,8 +202,11 @@ { // clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ] ) - { - broadcastAlarmCleared( alarm ); + { + if ( TRUE == isHDCommunicating() ) + { + broadcastAlarmCleared( alarm ); + } alarmIsActive[ alarm ] = FALSE; clearAlarmCondition( alarm ); } @@ -206,7 +234,10 @@ // clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmConditionIsActive[ alarm ] ) { - broadcastAlarmConditionCleared( alarm ); + if ( TRUE == isHDCommunicating() ) + { + broadcastAlarmConditionCleared( alarm ); + } alarmConditionIsActive[ alarm ] = FALSE; } } @@ -231,6 +262,28 @@ /*********************************************************************//** * @brief + * The publishAlarmInfo function publishes alarm information at the set + * interval. + * @details Inputs: + * @details Outputs: alarm information are published to CAN bus. + * @return none + *************************************************************************/ +static void publishAlarmInfo( void ) +{ + // Publish voltages monitor data on interval + if ( ++alarmInfoPublicationTimerCounter >= getU32OverrideValue( &alarmInfoPublishInterval ) ) + { + SAFETY_SHUTDOWN_ACTIVATION_DATA_T data; + + data.safetyShutdownStatus = (U32)isSafetyShutdownActivated(); + + broadcastData( MSG_ID_DG_ALARM_INFO, COMM_BUFFER_OUT_CAN_DG_ALARM, (U08*)&data, sizeof( SAFETY_SHUTDOWN_ACTIVATION_DATA_T ) ); + alarmInfoPublicationTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief * The checkPersistentAlarm function triggers/clears an alarm if an alarm condition * has persisted/cleared over given time limit. * @details Inputs: none @@ -241,8 +294,10 @@ * @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 checkPersistentAlarm( ALARM_ID_T alarm, BOOL const isErrorOccured, F32 const data, F32 const limit ) { + BOOL status = FALSE; + if ( TRUE == isPersistentAlarmTriggered( alarm, isErrorOccured ) ) { SET_ALARM_WITH_2_F32_DATA( alarm, data, limit ); @@ -251,9 +306,33 @@ if ( TRUE == isPersistentAlarmConditionCleared( alarm, isErrorOccured ) ) { clearAlarmCondition( alarm ); + status = TRUE; } + + return status; } +/*********************************************************************//** + * @brief +* The handleResendActiveAlarmsRequest function processes the request to re-send +* all active alarms. +* @details Inputs: alarmIsActive[] +* @details Outputs: re-send active alarms to UI +* @return none +*************************************************************************/ +void handleResendActiveAlarmsRequest( void ) +{ + U32 index; + + for ( index = 0; index < NUM_OF_ALARM_IDS; index++ ) + { + if ( TRUE == isAlarmActive( (ALARM_ID_T)index ) ) + { + broadcastAlarmTriggered( index, BLANK_ALARM_DATA, BLANK_ALARM_DATA ); + } + } +} + /************************************************************************* * TEST SUPPORT FUNCTIONS @@ -318,4 +397,93 @@ return result; } +/*********************************************************************//** + * @brief + * The testClearAllAlarms function clears all active alarms, even if they + * are non-recoverable or faults. The caller of this function must provide + * the correct 32-bit key. A Dialin user must also be logged into DG. + * @details Inputs: none + * @details Outputs: alarmIsActive[], alarmStartedAt[] + * @param key 32-bit supervior alarm key required to perform this function + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testClearAllAlarms( U32 key ) +{ + BOOL result = FALSE; + + // Verify key + if ( SUPERVISOR_ALARM_KEY == key ) + { + // Verify tester has logged in with HD + if ( TRUE == isTestingActivated() ) + { + ALARM_ID_T a; + + // Clear all active alarms + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == alarmIsActive[ a ] ) + { + ALARM_NAME_DATA_T data; + + data.alarmName = (U32)a; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_DG_ALARM, (U08*)&data, sizeof( ALARM_NAME_DATA_T ) ); + alarmIsActive[ a ] = FALSE; + } + } + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmInfoPublishIntervalOverride function sets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @param ms milliseconds between alarm info broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / TASK_GENERAL_INTERVAL; + + result = TRUE; + alarmInfoPublishInterval.ovData = intvl; + alarmInfoPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmInfoPublishIntervalOverride function resets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmInfoPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmInfoPublishInterval.override = OVERRIDE_RESET; + alarmInfoPublishInterval.ovData = alarmInfoPublishInterval.ovInitData; + } + + return result; +} + /**@}*/