/************************************************************************** * * Copyright (c) 2019-2019 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 Timers.c * * @date 07-Nov-2019 * @author S. Nash * * @brief Alarm Management service module. Provides general alarm management \n * functionality including support functions for triggering and clearing \n * specific alarms. * **************************************************************************/ #include "Common.h" #include "AlarmLamp.h" #include "Timers.h" #include "AlarmMgmt.h" // ********** private definitions ********** #pragma pack(push,1) typedef struct { 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 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 BOOL systemFault; // a system fault is active? BOOL stop; // we should be in controlled stop right now BOOL noClear; // no recovery will be possible BOOL noResume; // treatment may not be resumed at this time BOOL noRinseback; // rinseback may not be initiated at this time BOOL noEndTreatment; // ending the treatment is not an option at this time BOOL noNewTreatment; // no new treatments may be started even if current treatment is ended BOOL bypassDialyzer; // the dialyzer should be bypassed at this time } COMP_ALARM_STATUS_T; typedef struct { ALARM_PRIORITY_T alarmPriority; // priority of alarm U32 alarmEscalatesAfter; // time (s) after start when alarm will escalate if not cleared (zero indicates no escalation) ALARM_ID_T alarmEscalatesTo; // ID of alarm that this alarm will escalate to (ALARM_ID_NO_ALARM indicates no esclation) BOOL alarmIsFault; // alarm is a system fault? BOOL alarmStops; // alarm activation should cause a controlled stop BOOL alarmNoClear; // alarm cannot be cleared (unrecoverable)? BOOL alarmNoResume; // alarm prevents treatment resume BOOL alarmNoRinseback; // alarm prevents rinseback BOOL alarmNoEndTreatment; // alarm prevents ending treatment BOOL alarmNoNewTreatment; // alarm prevents any new treatments BOOL alarmDialyzerBypass; // alarm activation should cause dialyzer bypass until cleared } ALARM_T; typedef struct { BOOL alarmActive; // alarm is currently active? U32 alarmStart; // time stamp for when alarm was activated } ALARM_STATUS_T; #pragma pack(pop) const ALARM_T alarmTable[NUM_OF_ALARM_IDS] = { { ALARM_PRIORITY_NONE, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_NO_ALARM { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE } // ALARM_ID_SOFTWARE_FAULT }; // ********** private data ********** static ALARM_STATUS_T alarmStatusTable[NUM_OF_ALARM_IDS] = { { FALSE, 0 }, // ALARM_ID_NO_ALARM { FALSE, 0 } // ALARM_ID_SOFTWARE_FAULT }; static COMP_ALARM_STATUS_T alarmStatus; static ALARM_ID_T alarmPriorityFIFO[NUM_OF_ALARM_PRIORITIES]; // ********** private function prototypes ********** static void updateAlarmsState( void ); static void setAlarmLampAndAudio( void ); static void updateAlarmsSilenceStatus( void ); static void handleAlarmEscalations( void ); static void updateAlarmsFlags( void ); static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); /************************************************************************* * @brief initAlarmMgmt * The initAlarmMgmt function initializes the AlarmMgmt module. * @details * Inputs : none * Outputs : AlarmMgmt module initialized. * @param none * @return none *************************************************************************/ void initAlarmMgmt( void ) { ALARM_PRIORITY_T p; for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { alarmPriorityFIFO[p] = ALARM_ID_NO_ALARM; } alarmStatus.alarmsState = ALARM_PRIORITY_NONE; alarmStatus.alarmsSilenced = FALSE; alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmsEscalatesIn = 0; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; alarmStatus.systemFault = FALSE; alarmStatus.stop = FALSE; alarmStatus.noClear = FALSE; alarmStatus.noResume = FALSE; alarmStatus.noRinseback = FALSE; alarmStatus.noEndTreatment = FALSE; alarmStatus.noNewTreatment = FALSE; alarmStatus.bypassDialyzer = FALSE; } /************************************************************************* * @brief execAlarmMgmt * The execAlarmMgmt function executes the alarm management functions to be \n * done periodically. The composite alarm state is updated, alarm lamp and \n * audio patterns are updated, and status is sent out to the rest of the system. * @details * Inputs : larmStatusTable[], alarmTable[] * Outputs : larmStatus * @param none * @return none *************************************************************************/ void execAlarmMgmt( void ) { handleAlarmEscalations(); updateAlarmsState(); updateAlarmsFlags(); updateAlarmsSilenceStatus(); setAlarmLampAndAudio(); // TODO - publish alarms status record to rest of system } /************************************************************************* * @brief activateAlarm * The activateAlarm function activates a given alarm. Also, an alarm \n * message is broadcast to the rest of the system. * @details * Inputs : none * Outputs : AlarmStatusTable[] * @param alarm : ID of alarm to activate * @return none *************************************************************************/ void activateAlarm( ALARM_ID_T alarm ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { alarmStatusTable[alarm].alarmActive = TRUE; alarmStatusTable[alarm].alarmStart = getMSTimerCount(); // TODO - send alarm broadcast msg } else { // TODO - s/w fault } } /************************************************************************* * @brief activateAlarm1Data * The activateAlarm function activates a given alarm. Also, an alarm \n * message is broadcast to the rest of the system. This function will \n * include given data in the broadcast message for logging. * @details * Inputs : none * Outputs : AlarmStatusTable[] * @param alarm : ID of alarm to activate * @param alarmData : supporting data to include in alarm msg * @return none *************************************************************************/ void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { alarmStatusTable[alarm].alarmActive = TRUE; alarmStatusTable[alarm].alarmStart = getMSTimerCount(); // TODO - send alarm broadcast msg w/ alarm data } else { // TODO - s/w fault } } /************************************************************************* * @brief activateAlarm1Data * The activateAlarm function activates a given alarm. Also, an alarm \n * message is broadcast to the rest of the system. This function will \n * include two given data in the broadcast message for logging. * @details * Inputs : none * Outputs : AlarmStatusTable[] * @param alarm : ID of alarm to activate * @param alarmData1 : supporting data to include in alarm msg * @param alarmData2 : supporting data to include in alarm msg * @return none *************************************************************************/ void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { alarmStatusTable[alarm].alarmActive = TRUE; alarmStatusTable[alarm].alarmStart = getMSTimerCount(); // TODO - send alarm broadcast msg w/ alarm data } else { // TODO - s/w fault } } /************************************************************************* * @brief clearAlarm * The clearAlarm function clears a given alarm if it is recoverable. Also \n * an alarm message is broadcast to the rest of the system. * @details * Inputs : none * Outputs : AlarmStatusTable[] * @param alarm : ID of alarm to clear * @return none *************************************************************************/ void clearAlarm( ALARM_ID_T alarm ) { // verify given alarm if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { // verify alarm can be cleared if ( FALSE == alarmTable[alarm].alarmNoClear ) { alarmStatusTable[alarm].alarmActive = TRUE; alarmStatusTable[alarm].alarmStart = getMSTimerCount(); // clear FIFO if this alarm was in it if ( alarmPriorityFIFO[alarmTable[alarm].alarmPriority] == alarm ) { resetAlarmPriorityFIFO( alarmTable[alarm].alarmPriority ); } // TODO - send alarm broadcast msg w/ alarm data } } else { // TODO - s/w fault } } /************************************************************************* * @brief updateAlarmsState * The updateAlarmsState function updates the alarms state and alarm to \n * display. * @details * Inputs : alarmStatusTable[] * Outputs : alarmPriorityFIFO[], alarmStatus * @param none * @return none *************************************************************************/ static void updateAlarmsState( void ) { ALARM_ID_T tempDisp = ALARM_ID_NO_ALARM; ALARM_PRIORITY_T tempState = ALARM_PRIORITY_NONE; ALARM_ID_T a; ALARM_PRIORITY_T p; // update FIFOs per alarm status table for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { if ( TRUE == alarmStatusTable[a].alarmActive ) { if ( ALARM_ID_NO_ALARM == alarmPriorityFIFO[alarmTable[a].alarmPriority] ) { alarmPriorityFIFO[alarmTable[a].alarmPriority] = a; } } } // update alarms status and alarm to display per highest priority FIFO for ( p = ALARM_PRIORITY_LOW; p < NUM_OF_ALARM_PRIORITIES; p++ ) { tempState = p; tempDisp = alarmPriorityFIFO[p]; } alarmStatus.alarmsState = tempState; alarmStatus.alarmTop = tempDisp; } /************************************************************************* * @brief setAlarmLampAndAudio * The setAlarmLampAndAudio function sets the alarm lamp and audio patterns \n * according to the current state of alarms. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ static void setAlarmLampAndAudio( void ) { switch ( alarmStatus.alarmsState ) { case ALARM_PRIORITY_NONE: requestAlarmLampPattern( LAMP_PATTERN_OK ); // TODO - no audio break; case ALARM_PRIORITY_LOW: requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); // TODO - low priority audio break; case ALARM_PRIORITY_MEDIUM: requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); // TODO - medium priority audio break; case ALARM_PRIORITY_HIGH: if ( TRUE == alarmTable[alarmStatus.alarmTop].alarmIsFault ) { requestAlarmLampPattern( LAMP_PATTERN_FAULT ); } else { requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); } // TODO - high priority audio break; default: // TODO - s/w fault break; } } /************************************************************************* * @brief updateAlarmsSilenceStatus * The updateAlarmsSilenceStatus function updates the alarms silence state. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ static void updateAlarmsSilenceStatus( void ) { } /************************************************************************* * @brief handleAlarmEscalations * The handleAlarmEscalations function handles alarm escalation. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ static void handleAlarmEscalations( void ) { } /************************************************************************* * @brief updateAlarmsFlags * The updateAlarmsFlags function updates the alarms flags of the alarms \n * status record. * @details * Inputs : none * Outputs : none * @param none * @return none *************************************************************************/ static void updateAlarmsFlags( void ) { } /************************************************************************* * @brief resetAlarmPriorityFIFO * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm \n * priority. * @details * Inputs : none * Outputs : alarmPriorityFIFO[] * @param priority : priority of FIFO to reset * @return none *************************************************************************/ static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) { // verify priority if ( priority < NUM_OF_ALARM_PRIORITIES ) { alarmPriorityFIFO[priority] = ALARM_ID_NO_ALARM; } }