Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rf3ea910aef69d3abf485d97ac9a63af6304ca0c2 -r335c721d795f22c6dc4a24f5180dee3ba095a2b2 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision f3ea910aef69d3abf485d97ac9a63af6304ca0c2) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 335c721d795f22c6dc4a24f5180dee3ba095a2b2) @@ -8,7 +8,7 @@ * @file AlarmMgmt.c * * @author (last) Sean Nash -* @date (last) 21-Apr-2023 +* @date (last) 18-May-2023 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -114,9 +114,9 @@ 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 alarmsBlockedTimer = 0; ///< Countdown timer used to temporarily block new alarms from being initiated -static U32 audioTestStartTime; ///< Start time of audio alarm current self-test. static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. +static U32 audioTestStartTime; ///< Start time of audio alarm current self-test. +static U32 alarmsBlockedTimer = 0; ///< Countdown timer used to temporarily block new alarms from being initiated /// 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 }; @@ -252,6 +252,33 @@ /*********************************************************************//** * @brief + * The isACPowerLost function determines whether A/C power loss has + * been detected. This function sets the alarms blocked condition to + * allow smooth alarm recovery. + * + * @details Inputs: alarmStatus + * @details Outputs: alarmsBlockedTimer + * @return TRUE if A/C power loss alarm is in effect, FALSE if not + *************************************************************************/ +BOOL isACPowerLost( void ) +{ + BOOL result = TRUE; + + // Continue to block new alarms until the alarms are cleared. + if ( ( FALSE == isAlarmConditionDetected( ALARM_ID_HD_AC_POWER_LOST ) ) && + ( FALSE == isAlarmConditionDetected( ALARM_ID_HD_AC_POWER_LOST_IN_TREATMENT ) ) ) + { + result = FALSE; + } + else + { + alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; + } + return result; +} + +/*********************************************************************//** + * @brief * The activateAlarm function activates a given alarm. * @details Inputs: none * @details Outputs: alarmIsActive[], alarmStartedAt[], alarmStatus is updated @@ -260,13 +287,25 @@ *************************************************************************/ static void activateAlarm( ALARM_ID_T alarm ) { + // Block new alarms, occuring during loss of AC power + if ( ( TRUE == getCPLDACPowerLossDetected() ) ) + { + alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; + } // Verify valid alarm index 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 ) ) ) { + // If alarms are silenced and this new alarm is of higher or same priority, end silence due to new alarm + if ( ( ALARM_TABLE[ alarm ].alarmPriority > ALARM_TABLE[ alarmStatus.alarmTop ].alarmPriority ) || + ( ( ALARM_TABLE[ alarm ].alarmPriority == ALARM_TABLE[ alarmStatus.alarmTop ].alarmPriority ) && + ( ALARM_TABLE[ alarm ].alarmSubRank < ALARM_TABLE[ alarmStatus.alarmTop ].alarmSubRank ) ) ) + { + alarmStatus.alarmsSilenced = FALSE; + } // 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 ) { @@ -277,8 +316,6 @@ { 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 ) ) { @@ -351,12 +388,7 @@ * @return none *************************************************************************/ void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ) -{ - // Block if new alarms are occur during loss of AC power - if ( ( TRUE == getCPLDACPowerLossDetected() ) ) - { - alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; - } +{ // Sanity check, verify valid alarm index if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { @@ -1246,8 +1278,8 @@ // which will cause a fault for ( a = ( ( ALARM_ID_T ) 1 ) ; a < NUM_OF_ALARM_IDS; a++ ) { - // Is alarm recoverable? - if ( FALSE == ALARM_TABLE[ a ].alarmNoClear ) + // Clear alarm if alarm allowed to be cleared and not clear only (those are cleared individually) + if ( ( FALSE == ALARM_TABLE[ a ].alarmNoClear ) && ( FALSE == ALARM_TABLE[ a ].alarmClearOnly ) ) { clearAlarm( a ); } @@ -1308,6 +1340,7 @@ data.audioCurrLG = getAlarmAudioPrimaryLowGainCurrent(); data.backupAudioCurr = getAlarmAudioBackupCurrent(); data.safetyShutdown = isSafetyShutdownActivated(); + data.acPowerLost = getCPLDACPowerLossDetected(); data.uiAlarmButtonBlocks[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ]; data.uiAlarmButtonBlocks[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ]; data.uiAlarmButtonBlocks[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ];