Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f -rd4f6af7415f1fa6c149386121c6836fc6ef276e9 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision d4f6af7415f1fa6c149386121c6836fc6ef276e9) @@ -7,8 +7,8 @@ * * @file AlarmMgmt.c * -* @author (last) Dara Navaei -* @date (last) 18-Jan-2023 +* @author (last) Sean Nash +* @date (last) 31-Mar-2023 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -44,8 +44,7 @@ #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 MAX_ALARM_LIST_SIZE 10 ///< Maximum number of active alarms inside alarm list. +#define LOWEST_ALARM_SUB_RANK 999 ///< Lowest alarm sub-rank that can be set. // *** 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 ) ]; @@ -74,7 +73,7 @@ { ALARM_ID_T alarmID; ///< ID of highest priority alarm in this priority category U32 subRank; ///< Sub-rank of this alarm - U32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered + S32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered } ALARM_PRIORITY_RANKS_T; /// Enumeration of alarm audio self-test states. @@ -131,11 +130,11 @@ static BOOL alarmButtonBlockers[ NUM_OF_ALARM_BUTTON_BLOCKERS ]; ///< Flags indicating whether alarm table or state properties are blocking alarm buttons for UI. -/// Current state of the alarm audio self tests. -static ALARM_AUDIO_SELF_TEST_STATE_T alarmAudioSelfTestState; -/// Flag indicates whether alarm audio test tone should be output. -static BOOL alarmAudioTestToneRequested; +static ALARM_AUDIO_SELF_TEST_STATE_T alarmAudioSelfTestState; ///< Current state of the alarm audio self tests. +static BOOL alarmAudioTestToneRequested; ///< Flag indicates whether alarm audio test tone should be output. +static BOOL resumeBlockedByAlarmProperty; ///< Flag indicates whether treatment resumption is currently blocked by alarm property. + // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); @@ -145,7 +144,6 @@ static void setAlarmLamp( void ); static void setAlarmAudio( void ); static void updateAlarmsSilenceStatus( void ); -static void handleAlarmEscalations( void ); static void updateAlarmsFlags( void ); static void clearAllRecoverableAlarms( void ); @@ -198,7 +196,8 @@ alarmStatus.alarmsSilenced = FALSE; alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; - alarmStatus.alarmsEscalatesIn = 0; + alarmStatus.alarmsEscalatesIn = 0; + alarmStatus.alarmsToEscalate = FALSE; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; alarmStatus.topAlarmConditionDetected = FALSE; alarmStatus.systemFault = FALSE; @@ -213,6 +212,7 @@ alarmStatus.ok = FALSE; alarmAudioTestToneRequested = FALSE; + resumeBlockedByAlarmProperty = FALSE; alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; } @@ -228,7 +228,6 @@ void execAlarmMgmt( void ) { monitorAlarms(); - handleAlarmEscalations(); updateAlarmsState(); updateAlarmsFlags(); updateAlarmsSilenceStatus(); @@ -258,6 +257,11 @@ { 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 @@ -522,7 +526,8 @@ break; case ALARM_USER_ACTION_END_TREATMENT: - initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); + // Send message to UI to get user confirmation to end treatment - action initiated only upon receipt of user confirmation from UI + addConfirmationRequest( GENERIC_CONFIRM_ID_TREATMENT_END, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); break; case ALARM_USER_ACTION_ACK: @@ -644,6 +649,19 @@ /*********************************************************************//** * @brief + * The doesAlarmIndicateNoResume function determines whether any currently + * active alarm has treatment resume blocked property. + * @details Inputs: resumeBlockedByAlarmProperty + * @details Outputs: none + * @return TRUE if any active alarm has no resume property, FALSE if not + *************************************************************************/ +BOOL doesAlarmIndicateNoResume( void ) +{ + return resumeBlockedByAlarmProperty; +} + +/*********************************************************************//** + * @brief * The getCurrentAlarmStatePriority function determines the current alarm * state priority (NONE, LOW, MEDIUM, or HIGH). * @details Inputs: alarmStatus @@ -710,16 +728,17 @@ *************************************************************************/ void handleActiveAlarmListRequest( void ) { - BOOL accepted = TRUE; - REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; - U32 activeAlarmList[ MAX_ALARM_LIST_SIZE ]; + ACTIVE_ALARM_LIST_RESPONSE_PAYLOAD_T activeAlarmPayload; U32 index; U32 activeAlarmListIndex = 0; + activeAlarmPayload.accepted = TRUE; + activeAlarmPayload.rejectionReason = (U32)REQUEST_REJECT_REASON_NONE; + // Blank alarm list initially for ( index = 0; index < MAX_ALARM_LIST_SIZE; index++ ) { - activeAlarmList[ index ] = ALARM_ID_NO_ALARM; + activeAlarmPayload.activeAlarmList[ index ] = ALARM_ID_NO_ALARM; } // Fill alarm list from (up to) 10 highest priority active alarms @@ -729,13 +748,13 @@ { if ( ( TRUE == isAlarmActive( ALARM_RANK_TABLE[ index ].alarmID ) ) && ( activeAlarmListIndex < MAX_ALARM_LIST_SIZE ) ) { - activeAlarmList[ activeAlarmListIndex ] = ALARM_RANK_TABLE[ index ].alarmID; + activeAlarmPayload.activeAlarmList[ activeAlarmListIndex ] = ALARM_RANK_TABLE[ index ].alarmID; activeAlarmListIndex++; } } } - sendActiveAlarmsList( accepted, rejReason, activeAlarmList, sizeof( activeAlarmList ) ); + sendActiveAlarmsList( activeAlarmPayload ); } /*********************************************************************//** @@ -819,6 +838,12 @@ alarmPrimaryAudioCurrentLG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); alarmBackupAudioCurrent.data = getFPGABackupAlarmAudioCurrent(); + // Check for user confirmation of end treatment alarm response + if ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == getConfirmationRequestStatus( GENERIC_CONFIRM_ID_TREATMENT_END ) ) + { + initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); + } + // TODO - Check current vs. expected audio output } @@ -859,19 +884,19 @@ // If sub-rank is a tie, see which alarm was triggered first if ( subRank == alarmPriorityFIFO[ almPriority ].subRank ) { - if ( msSinceTriggered > alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS ) + if ( (S32)msSinceTriggered > alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS ) { alarmPriorityFIFO[ almPriority ].alarmID = a; alarmPriorityFIFO[ almPriority ].subRank = subRank; - alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = (S32)msSinceTriggered; } } // Otherwise, this alarm simply outranks current candidate and wins outright else { alarmPriorityFIFO[ almPriority ].alarmID = a; alarmPriorityFIFO[ almPriority ].subRank = subRank; - alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = (S32)msSinceTriggered; } } // Track highest priority alarm found so far of all priority categories @@ -1000,22 +1025,21 @@ if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) { #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - setAlarmAudioState( ALARM_PRIORITY_HIGH, - ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], - ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); - } - - else + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) != SW_CONFIG_ENABLE_VALUE ) #endif { setAlarmAudioState( alarmStatus.alarmsState, ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); } } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_AUDIO_INVALID_ALARM_STATE, alarmStatus.alarmsState ) + setAlarmAudioState( ALARM_PRIORITY_HIGH, + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); + } } } @@ -1053,70 +1077,9 @@ } } } - + /*********************************************************************//** * @brief - * The handleAlarmEscalations function handles alarm escalation. - * @details Inputs: alarmIsActive[], ALARM_TABLE[] - * @details Outputs: alarm(s) escalated when appropriate - * @return none - *************************************************************************/ -static void handleAlarmEscalations( void ) -{ - U32 secsToEscalate = 0; - ALARM_ID_T nextAlarmToEscalate = ALARM_ID_NO_ALARM; - ALARM_ID_T a; - - // Update escalations - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { - if ( TRUE == alarmIsActive[ a ] ) - { - // Does active alarm escalate? - if ( ALARM_ID_NO_ALARM != ALARM_TABLE[ a ].alarmEscalatesTo ) - { - S32 msRemaining = (S32)ALARM_TABLE[ a ].alarmEscalatesAfter - (S32)calcTimeSince( getAlarmStartTime( a ) ); - S32 secsRemaining = ( msRemaining / MS_PER_SECOND ) + 1; - - // Time to escalate? - if ( msRemaining <= 0 ) - { - activateAlarmNoData( ALARM_TABLE[ a ].alarmEscalatesTo ); - clearAlarm( a ); - } - else - { // No candidates for alarm escalation yet? - if ( ALARM_ID_NO_ALARM == nextAlarmToEscalate ) - { - secsToEscalate = secsRemaining; - nextAlarmToEscalate = a; - } - // Sooner candidate for alarm escalation? - else if ( secsRemaining < secsToEscalate ) - { - secsToEscalate = secsRemaining; - nextAlarmToEscalate = a; - } - } - } // If alarm escalates - } // If alarm active - } // Alarm table loop - - // Update alarm escalation properties - if ( TRUE == alarmStatus.systemFault || ALARM_ID_NO_ALARM == nextAlarmToEscalate ) - { - alarmStatus.alarmsToEscalate = FALSE; - alarmStatus.alarmsEscalatesIn = 0; - } - else - { - alarmStatus.alarmsToEscalate = TRUE; - alarmStatus.alarmsEscalatesIn = secsToEscalate; - } -} - -/*********************************************************************//** - * @brief * The updateAlarmsFlags function updates the alarms flags of the alarms * status record. * @details Inputs: alarmStatus, alarmIsActive, ALARM_TABLE, alarmButtonBlockers @@ -1128,7 +1091,8 @@ BOOL systemFault = FALSE; BOOL stop = FALSE; BOOL noClear = FALSE; - BOOL noResume = FALSE; + BOOL noResume = FALSE; + BOOL noResumePerAlarmPropertyOnly = FALSE; BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; BOOL usrAckReq = FALSE; @@ -1153,6 +1117,7 @@ systemFault = ( TRUE == ALARM_TABLE[ a ].alarmIsFault ? TRUE : systemFault ); stop = ( TRUE == ALARM_TABLE[ a ].alarmStops ? TRUE : stop ); noClear = ( TRUE == ALARM_TABLE[ a ].alarmNoClear ? TRUE : noClear ); + noResumePerAlarmPropertyOnly = ( ALARM_TABLE[ a ].alarmNoResume ? TRUE : noResumePerAlarmPropertyOnly ); // Set user alarm recovery actions allowed flags alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] |= ALARM_TABLE[ a ].alarmNoResume; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] |= ALARM_TABLE[ a ].alarmNoRinseback; @@ -1217,7 +1182,8 @@ alarmStatus.noRinseback = noRinseback; alarmStatus.noEndTreatment = noEndTreatment; alarmStatus.ok = usrAckReq; - alarmStatus.noMinimize = noMinimize; + alarmStatus.noMinimize = noMinimize; + resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; } /*********************************************************************//** @@ -1232,7 +1198,7 @@ { ALARM_ID_T a = alarmStatus.alarmTop; - for ( a = ALARM_ID_HD_SOFTWARE_FAULT; a < NUM_OF_ALARM_IDS; a++ ) + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { // Is alarm recoverable? if ( FALSE == ALARM_TABLE[ a ].alarmNoClear ) @@ -1258,7 +1224,7 @@ { alarmPriorityFIFO[ priority ].alarmID = ALARM_ID_NO_ALARM; alarmPriorityFIFO[ priority ].subRank = LOWEST_ALARM_SUB_RANK; - alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = 0; + alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = -1; } else { @@ -1303,7 +1269,7 @@ data.uiAlarmButtonBlocks[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ]; data.uiAlarmButtonBlocks[ ALARM_BUTTON_STATE_BLOCK_END_TREATMENT ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_END_TREATMENT ]; - broadcastData( MSG_ID_HD_ALARM_INFORMATION, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( ALARM_INFO_PAYLOAD_T ) ); + broadcastData( MSG_ID_HD_ALARM_INFORMATION_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( ALARM_INFO_PAYLOAD_T ) ); alarmInfoPublicationTimerCounter = 0; } }