Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rc1b9ac0dbf2196280895d2e440dd7ac288ac8424 -r9e88617fa7eef0fd2ccc9a69facbf07437777490 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision c1b9ac0dbf2196280895d2e440dd7ac288ac8424) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 9e88617fa7eef0fd2ccc9a69facbf07437777490) @@ -39,12 +39,17 @@ #define ALARM_STATUS_PUBLISH_INTERVAL ( ALARM_LAMP_AND_AUDIO_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) /// 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 ) + +/// Interval (ms/task time) at which the alarm information is published on the CAN bus. +#define ALARM_BLOCK_COUNT_AFTER_AC_RETURN ( 10*MS_PER_SECOND / TASK_GENERAL_INTERVAL ) -#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. +#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. -#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. +#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. -#define LOWEST_ALARM_SUB_RANK 999 ///< Lowest alarm sub-rank that can be set. +#define LOWEST_ALARM_SUB_RANK 999 ///< Lowest alarm sub-rank that can be set. +#define ALARM_BLOCKED_LIMIT_AC_RECOVERY 10 ///< Alarm rank above which alarms are blocked by alarmStatus.alarmsBlockedTimer, last unblockable alarm +#define ALARM_NOT_BLOCKED 0 ///< Alarm blocked timer value that indicates no alarm block // *** 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 ) ]; @@ -108,7 +113,7 @@ static BOOL alarmIsDetected[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm condition (detected or cleared) static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< Table - when alarm became active for each alarm (if active) or zero (if inactive) static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. -static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. +static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. /// Interval (in task intervals) at which to publish alarm status to CAN bus. static OVERRIDE_U32_T alarmStatusPublishInterval = { ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, 0 }; @@ -195,7 +200,8 @@ alarmStatus.alarmsState = ALARM_PRIORITY_NONE; alarmStatus.alarmsSilenced = FALSE; alarmStatus.alarmsSilenceStart = 0; - alarmStatus.alarmsSilenceExpiresIn = 0; + alarmStatus.alarmsSilenceExpiresIn = 0; + alarmStatus.alarmsBlockedTimer = 0; alarmStatus.alarmsEscalatesIn = 0; alarmStatus.alarmsToEscalate = FALSE; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; @@ -233,62 +239,78 @@ updateAlarmsSilenceStatus(); // Publish alarm status and information at interval publishAlarmInfo(); + + // Block new machine alarms during power fail recovery + if ( alarmStatus.alarmsBlockedTimer > 0 ) + { + alarmStatus.alarmsBlockedTimer--; + } } - -/*********************************************************************//** - * @brief - * The activateAlarm function activates a given alarm. - * @details Inputs: none - * @details Outputs: alarmIsActive[], alarmStartedAt[] - * @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, but if condition was cleared then re-trigger alarm - if ( ( FALSE == alarmIsActive[ alarm ] ) || - ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) + +/*********************************************************************//** + * @brief + * The activateAlarm function activates a given alarm. + * @details Inputs: none + * @details Outputs: alarmIsActive[], alarmStartedAt[], alarmStatus is updated + * @param alarm ID of alarm to activate + * @return none + *************************************************************************/ +static void activateAlarm( ALARM_ID_T alarm ) +{ + // Verify valid alarm index + if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) + { + // Block if new alarms are occur during loss of AC power + if ( ( TRUE == alarmIsActive[ ALARM_ID_HD_AC_POWER_LOST ] ) || ( TRUE == alarmIsActive[ ALARM_ID_HD_AC_POWER_LOST_IN_TREATMENT ] ) ) { - // If alarm status was that no alarms currently active, set this alarm as top alarm until status formally updated later - if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) + alarmStatus.alarmsBlockedTimer = ALARM_BLOCK_COUNT_AFTER_AC_RETURN; + } + // if the block timer is 0 OR we have an unblockable alarm + if (( ALARM_NOT_BLOCKED == alarmStatus.alarmsBlockedTimer ) || ( ALARM_TABLE[ alarm ].alarmSubRank <= ALARM_BLOCKED_LIMIT_AC_RECOVERY ) ) + { + // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm + if ( ( FALSE == alarmIsActive[ alarm ] ) || + ( ( FALSE == alarmIsDetected[ alarm ] ) && ( FALSE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) ) ) { - alarmStatus.alarmTop = alarm; + // If alarm status was that no alarms currently active, set this alarm as top alarm until status formally updated later + if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) + { + alarmStatus.alarmTop = alarm; + } + // If alarm stops, set that status immediately (don't wait for status update function) + if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) + { + alarmStatus.stop = TRUE; + } + // If alarms silenced, end silence due to new alarm + alarmStatus.alarmsSilenced = FALSE; + // If alarm is a fault (and not in service mode), request transition to fault mode + if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) + { + requestNewOperationMode( MODE_FAUL ); + } + // Activate alarm + alarmIsActive[ alarm ] = TRUE; + alarmStartedAt[ alarm ].data = getMSTimerCount(); + alarmIsDetected[ alarm ] = TRUE; + + // If alarm has clear condition immediately property, clear condition now + if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) + { + clearAlarmCondition( alarm ); + } + // If alarm has stop property, signal stop now + if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) + { + initiateAlarmAction( ALARM_ACTION_STOP ); + } } - // If alarm stops, set that status immediately (don't wait for status update function) - if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) - { - alarmStatus.stop = TRUE; - } - // If alarms silenced, end silence due to new alarm - alarmStatus.alarmsSilenced = FALSE; - // If alarm is a fault (and not in service mode), request transition to fault mode - if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) - { - requestNewOperationMode( MODE_FAUL ); - } - // Activate alarm - alarmIsActive[ alarm ] = TRUE; - alarmStartedAt[ alarm ].data = getMSTimerCount(); - alarmIsDetected[ alarm ] = TRUE; - // If alarm has clear condition immediately property, clear condition now - if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) - { - clearAlarmCondition( alarm ); - } - // If alarm has stop property, signal stop now - if ( TRUE == ALARM_TABLE[ alarm ].alarmStops ) - { - initiateAlarmAction( ALARM_ACTION_STOP ); - } - } + } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) - } + } } /*********************************************************************//** Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r1d07de4e970f54f2ae1786ef546cf5567df9ba8e -r9e88617fa7eef0fd2ccc9a69facbf07437777490 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 1d07de4e970f54f2ae1786ef546cf5567df9ba8e) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 9e88617fa7eef0fd2ccc9a69facbf07437777490) @@ -61,7 +61,8 @@ ALARM_PRIORITY_T alarmsState; ///< Current alarm priority level BOOL alarmsSilenced; ///< Alarms are currently silenced? U32 alarmsSilenceStart; ///< Time stamp for when alarms were silenced (ms) - U32 alarmsSilenceExpiresIn; ///< Time until alarm silence expires (seconds) + U32 alarmsSilenceExpiresIn; ///< Time until alarm silence expires (seconds) + U32 alarmsBlockedTimer; ///< Time used to temporarily block alarms during recovery from AC power fail BOOL alarmsToEscalate; ///< Are any active alarms due to escalate (should UI show count down timer?) U32 alarmsEscalatesIn; ///< Time until alarm will escalate (seconds) ALARM_ID_T alarmTop; ///< ID of current top alarm that will drive lamp/audio and UI should be displaying right now