/************************************************************************** * * Copyright (c) 2019-2020 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 * * @author (last) Sean Nash * @date (last) 24-Jun-2020 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 * ***************************************************************************/ #include "mibspi.h" #include "AlarmLamp.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" /** * @addtogroup AlarmManagement * @{ */ // ********** private definitions ********** #define ALARM_STATUS_PUBLISH_INTERVAL (500/TASK_GENERAL_INTERVAL) ///< Default interval to publish alarm status data. #define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. #define ALM_ESC_1_MIN (1 * SEC_PER_MIN * MS_PER_SECOND) ///< Number of ms in 1 minute. #define ALM_ESC_4_MIN (4 * SEC_PER_MIN * MS_PER_SECOND) ///< Number of ms in 4 minutes. #define ALM_ESC_5_MIN (5 * SEC_PER_MIN * MS_PER_SECOND) ///< Number of ms in 5 minutes. #define ALM_ESC_10_MIN (10 * SEC_PER_MIN * MS_PER_SECOND) ///< Number of ms in 10 minutes. #pragma pack(push,1) /// Record defining the properties of each individual alarm. 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 escalation) 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; #pragma pack(pop) /// Table of alarms and their static properties. const ALARM_T alarmTable[ NUM_OF_ALARM_IDS ] = { // Priority Escalate In Escalate To Fault Stops NoClr NoRes NoRin NoEnd NoNew Bypass { 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_HD_SOFTWARE_FAULT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_STUCK_BUTTON_TEST_FAILED { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_FPGA_POST_TEST_FAILED { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_WATCHDOG_POST_TEST_FAILED { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_UI_COMM_POST_FAILED { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_OFF_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_MC_CURRENT_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_OFF_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_MC_DIRECTION_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_ROTOR_SPEED_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_MC_CURRENT_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_OFF_CHECK { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_MC_DIRECTION_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_ROTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_WATCHDOG_EXPIRED { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_RTC_COMM_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_RTC_CONFIG_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_COMM_TIMEOUT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_UI_COMM_TIMEOUT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_COMM_TOO_MANY_BAD_CRCS { ALARM_PRIORITY_LOW, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_TREATMENT_STOPPED_BY_USER { ALARM_PRIORITY_MEDIUM, ALM_ESC_1_MIN, ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RESUME, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_SITTING_WARNING { ALARM_PRIORITY_MEDIUM, ALM_ESC_5_MIN, ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RINSEBACK, FALSE, TRUE , FALSE, TRUE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RESUME { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, TRUE , FALSE, TRUE, TRUE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_SITTING_TOO_LONG_NO_RINSEBACK { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_CAN_MESSAGE_NOT_ACKED { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_OCCLUSION_BLOOD_PUMP { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_OCCLUSION_DIAL_IN_PUMP { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_OCCLUSION_DIAL_OUT_PUMP { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_ARTERIAL_PRESSURE_LOW { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_ARTERIAL_PRESSURE_HIGH { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_VENOUS_PRESSURE_LOW { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_VENOUS_PRESSURE_HIGH { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_UF_RATE_TOO_HIGH_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_UF_VOLUME_ACCURACY_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_RTC_BATTERY_LOW { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_RTC_OR_TIMER_ACCURACY_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_RTC_RAM_OPS_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_NVDATA_EEPROM_OPS_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_NVDATA_MFG_RECORD_CRC_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_NVDATA_SRVC_RECORD_CRC_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_NVDATA_CAL_RECORD_CRC_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_NVDATA_HW_USAGE_DATA_CRC_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // AlARM_ID_NVDATA_DISINFECTION_DATE_CRC_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_RO_PUMP_OUT_PRESSURE_OUT_OF_RANGE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_TEMPERATURE_SENSORS_OUT_OF_RANGE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_TEMPERATURE_SENSORS_INCONSISTENT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_HD_COMM_TIMEOUT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE, TRUE , TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ALARM_ID_VALVE_CONTROL_FAILURE { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_FLOW_VS_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_FLOW_VS_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_IN_PUMP_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DIAL_OUT_PUMP_MOTOR_SPEED_CHECK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_INLET_WATER_LOW_CONDUCTIVITY { ALARM_PRIORITY_MEDIUM, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_SOFTWARE_FAULT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_CONDUCTIVITY_SENSOR_FAULT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_INLET_WATER_LOW_TEMPERATURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_INLET_WATER_HIGH_TEMPERATURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_PRESSURE_SENSOR_FAULT { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_INLET_WATER_LOW_PRESSURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_CRITICAL_DATA_ERROR { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_HD_ACCELEROMETER_SELF_TEST_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_ACCELEROMETER_SELF_TEST_FAILURE { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_HD_EXCESSIVE_TILT { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DG_EXCESSIVE_TILT { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_HD_SHOCK { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_DG_SHOCK { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_HD_ACCELEROMETER_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_ACCELEROMETER_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_CRITICAL_DATA_ERROR { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE }; /// A blank alarm data record for alarms that do not include alarm data when triggered. const ALARM_DATA_T blankAlarmData = { ALARM_DATA_TYPE_NONE, 0 }; // pin assignment for backup alarm audio enable #define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 ///< pin SPI3-CS0 - re-purposed as output GPIO for back audio enable. // backup alarm audio enable/disable macros #define SET_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 |= BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to enable backup alarm audio. #define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. // ********** private data ********** /// interval (in ms) at which to publish alarm status to CAN bus DATA_DECL( U32, AlarmStatusPub, alarmStatusPublishInterval, ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL ); static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. /// table - current state of each alarm static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; /// table - when alarm became active for each alarm (if active) or zero (if inactive) DATA_ARRAY_DECL( U32, AlarmStarts, NUM_OF_ALARM_IDS, alarmStartedAt ); static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. static ALARM_ID_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; ///< FIFO - first activated alarm in each alarm priority category. // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); 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 ); static DATA_ARRAY_GET_PROTOTYPE( U32, getAlarmStartTime, alarmID ); static DATA_GET_PROTOTYPE( U32, getPublishAlarmStatusInterval ); /*********************************************************************//** * @brief * The initAlarmMgmt function initializes the AlarmMgmt module. * @details * Inputs : none * Outputs : AlarmMgmt module initialized. * @return none *************************************************************************/ void initAlarmMgmt( void ) { ALARM_PRIORITY_T p; ALARM_ID_T a; // disable backup audio CLR_BACKUP_AUDIO_ENABLE(); // initialize alarm states and start time stamps for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { alarmIsActive[ a ] = FALSE; alarmStartedAt[ a ].data = 0; alarmStartedAt[ a ].ovData = 0; alarmStartedAt[ a ].ovInitData = 0; alarmStartedAt[ a ].override = OVERRIDE_RESET; } // initialize alarm FIFOs for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { alarmPriorityFIFO[ p ] = ALARM_ID_NO_ALARM; } // initialize composite alarm state 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 * The execAlarmMgmt function executes the alarm management functions to be * done periodically. The composite alarm state is updated, alarm lamp and * audio patterns are updated, and status is sent out to the rest of the system. * @details * Inputs : alarmStatusTable[], alarmTable[] * Outputs : alarmStatus * @return none *************************************************************************/ void execAlarmMgmt( void ) { handleAlarmEscalations(); updateAlarmsState(); updateAlarmsFlags(); updateAlarmsSilenceStatus(); setAlarmLampAndAudio(); // publish alarm status at interval if ( ++alarmStatusPublicationTimerCounter >= getPublishAlarmStatusInterval() ) { broadcastAlarmStatus( alarmStatus ); alarmStatusPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The activateAlarm function activates a given alarm. * @details * Inputs : none * 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 if ( FALSE == alarmIsActive[ alarm ] ) { // if alarms silenced, end silence due to new alarm alarmStatus.alarmsSilenced = FALSE; // if alarm is a fault, request transition to fault mode if ( TRUE == alarmTable[ alarm ].alarmIsFault ) { #ifndef RM46_EVAL_BOARD_TARGET requestNewOperationMode( MODE_FAUL ); #endif } // activate alarm alarmIsActive[ alarm ] = TRUE; alarmStartedAt[ alarm ].data = getMSTimerCount(); } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, alarm ) } } /*********************************************************************//** * @brief * The activateAlarmNoData function activates a given alarm. Also, an alarm * message is broadcast to the rest of the system. This function will * include given data in the broadcast message for logging. * @details * Inputs : none * Outputs : alarm triggered message sent, alarm activated * @param alarm ID of alarm to activate * @return none *************************************************************************/ void activateAlarmNoData( ALARM_ID_T alarm ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, blankAlarmData, blankAlarmData ); } activateAlarm( alarm ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG if ( FALSE == alarmIsActive[ alarm ] ) { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d \n", alarm ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } /*********************************************************************//** * @brief * The activateAlarm1Data function activates a given alarm. Also, an alarm * message is broadcast to the rest of the system. This function will * include given data in the broadcast message for logging. * @details * Inputs : none * Outputs : alarm triggered message sent, alarm activated * @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 ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, alarmData, blankAlarmData ); } activateAlarm( alarm ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG if ( FALSE == alarmIsActive[ alarm ] ) { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d %8X \n", alarm, alarmData.data.uInt.data ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } /*********************************************************************//** * @brief * The activateAlarm2Data function activates a given alarm. Also, an alarm * message is broadcast to the rest of the system. This function will * include two given data in the broadcast message for logging. * @details * Inputs : none * Outputs : alarm triggered message sent, alarm activated * @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 ) { // broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) { broadcastAlarmTriggered( (U16)alarm, alarmData1, alarmData2 ); } activateAlarm( alarm ); #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG if ( FALSE == alarmIsActive[ alarm ] ) { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM trig:%5d %8X %8X \n", (S32)alarm, alarmData1.data.uInt.data, alarmData2.data.uInt.data ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } /*********************************************************************//** * @brief * The clearAlarm function clears a given alarm if it is recoverable. Also * 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 ) { // clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ] ) { broadcastAlarmCleared( alarm ); alarmIsActive[ alarm ] = FALSE; alarmStartedAt[ alarm ].data = 0; // clear FIFO if this alarm was in it if ( alarmPriorityFIFO[ alarmTable[ alarm ].alarmPriority ] == alarm ) { resetAlarmPriorityFIFO( alarmTable[ alarm ].alarmPriority ); } #ifdef DEBUG_ENABLED #ifdef ALARMS_DEBUG { // TODO - temporary debug code - remove later char debugStr[ 256 ]; sprintf( debugStr, "ALARM cleared:%5d \n", alarm ); sendDebugData( (U08*)debugStr, strlen(debugStr) ); sendDebugDataToUI( (U08*)debugStr ); } #endif #endif } } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, alarm ) } } /*********************************************************************//** * @brief * The isAlarmActive function determines whether a given alarm is currently * active. * @details * Inputs : alarmIsActive[] * Outputs : none * @param alarm ID of alarm to check * @return TRUE if given alarm is active, FALSE if not *************************************************************************/ BOOL isAlarmActive( ALARM_ID_T alarm ) { BOOL result = alarmIsActive[ alarm ]; return result; } /*********************************************************************//** * @brief * The getAlarmStartTime function gets the active state of a given alarm. * @details * Inputs : alarmStartedAt[] * Outputs : none * @param alarmID ID of alarm to check * @return The start time stamp of given alarm ID *************************************************************************/ U32 getAlarmStartTime( U32 alarmID ) { U32 result = 0; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( OVERRIDE_KEY == alarmStartedAt[ alarmID ].override ) { result = alarmStartedAt[ alarmID ].ovData; } else { result = alarmStartedAt[ alarmID ].data; } } else { activateAlarmNoData( ALARM_ID_HD_SOFTWARE_FAULT ); } return result; } /*********************************************************************//** * @brief * The updateAlarmsState function updates the alarms state and alarm to * display. * @details * Inputs : alarmStatusTable[] * Outputs : alarmPriorityFIFO[], alarmStatus * @return none *************************************************************************/ static void updateAlarmsState( void ) { ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE; ALARM_ID_T a; BOOL faultsActive = FALSE; // update FIFOs per active alarms table for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { if ( TRUE == alarmIsActive[a] ) { ALARM_PRIORITY_T almPriority = alarmTable[ a ].alarmPriority; if ( ALARM_ID_NO_ALARM == alarmPriorityFIFO[ almPriority ] ) { alarmPriorityFIFO[ almPriority ] = a; } highestPriority = MAX( almPriority, highestPriority ); if ( TRUE == alarmTable[ a ].alarmIsFault ) { faultsActive = TRUE; } } } // update alarm to display per highest priority FIFO alarmStatus.alarmsState = highestPriority; alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ]; alarmStatus.systemFault = faultsActive; } /*********************************************************************//** * @brief * The setAlarmLampAndAudio function sets the alarm lamp and audio patterns * according to the current state of alarms. * @details * Inputs : none * Outputs : Alarm lamp patter set according to current alarms status. * @return none *************************************************************************/ static void setAlarmLampAndAudio( void ) { if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) { switch ( alarmStatus.alarmsState ) { case ALARM_PRIORITY_NONE: requestAlarmLampPattern( LAMP_PATTERN_OK ); break; case ALARM_PRIORITY_LOW: requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); break; case ALARM_PRIORITY_MEDIUM: requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); break; case ALARM_PRIORITY_HIGH: if ( TRUE == alarmTable[ alarmStatus.alarmTop ].alarmIsFault ) { requestAlarmLampPattern( LAMP_PATTERN_FAULT ); } else { requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); } break; default: requestAlarmLampPattern( LAMP_PATTERN_FAULT ); SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) break; } } if ( TRUE == alarmStatus.alarmsSilenced ) { // TODO - no audio } else // alarms not silenced { switch ( alarmStatus.alarmsState ) { case ALARM_PRIORITY_NONE: // TODO - no audio break; case ALARM_PRIORITY_LOW: // TODO - low priority audio break; case ALARM_PRIORITY_MEDIUM: // TODO - medium priority audio break; case ALARM_PRIORITY_HIGH: // TODO - high priority audio break; default: // TODO - high priority audio SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) break; } } } /*********************************************************************//** * @brief * The updateAlarmsSilenceStatus function updates the alarms silence state. * @details * Inputs : alarmStatus * Outputs : alarmStatus * @return none *************************************************************************/ static void updateAlarmsSilenceStatus( void ) { // if alarms not silenced, reset alarms silence related properties if ( TRUE != alarmStatus.alarmsSilenced ) { alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmsSilenceStart = 0; } else { U32 timeSinceAlarmSilenceStart = calcTimeSince( alarmStatus.alarmsSilenceStart ) / MS_PER_SECOND; if ( timeSinceAlarmSilenceStart >= ALARM_SILENCE_EXPIRES_IN_SECS ) { alarmStatus.alarmsSilenceExpiresIn = 0; } else { alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; } // if alarms silence expires, end it if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) { alarmStatus.alarmsSilenced = FALSE; } } } /*********************************************************************//** * @brief * The handleAlarmEscalations function handles alarm escalation. * @details * Inputs : alarmIsActive[], alarmTable[] * 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 != alarmTable[ a ].alarmEscalatesTo ) { S32 msRemaining = (S32)alarmTable[ a ].alarmEscalatesAfter - (S32)calcTimeSince( getAlarmStartTime( a ) ); S32 secsRemaining = ( msRemaining / MS_PER_SECOND ) + 1; // time to escalate? if ( msRemaining <= 0 ) { activateAlarmNoData( alarmTable[ 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 : none * Outputs : alarmStatus * @return none *************************************************************************/ static void updateAlarmsFlags( void ) { BOOL systemFault = FALSE; BOOL stop = FALSE; BOOL noClear = FALSE; BOOL noResume = FALSE; BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; BOOL noNewTreatment = FALSE; BOOL bypassDialyzer = FALSE; ALARM_ID_T a; // determine alarm flags for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { if ( TRUE == alarmIsActive[ a ] ) { systemFault = ( TRUE == alarmTable[ a ].alarmIsFault ? TRUE : systemFault ); stop = ( TRUE == alarmTable[ a ].alarmStops ? TRUE : stop ); noClear = ( TRUE == alarmTable[ a ].alarmNoClear ? TRUE : noClear ); noResume = ( TRUE == alarmTable[ a ].alarmNoResume ? TRUE : noResume ); noRinseback = ( TRUE == alarmTable[ a ].alarmNoRinseback ? TRUE : noRinseback ); noEndTreatment = ( TRUE == alarmTable[ a ].alarmNoEndTreatment ? TRUE : noEndTreatment ); noNewTreatment = ( TRUE == alarmTable[ a ].alarmNoNewTreatment ? TRUE : noNewTreatment ); bypassDialyzer = ( TRUE == alarmTable[ a ].alarmDialyzerBypass ? TRUE : bypassDialyzer ); } // if alarm active } // alarm table loop // do not bypass dialyzer if stop or fault flag set if ( ( TRUE == systemFault ) || ( TRUE == stop ) ) { bypassDialyzer = FALSE; } // set updated alarm flags alarmStatus.systemFault = systemFault; alarmStatus.stop = stop; alarmStatus.noClear = noClear; alarmStatus.noResume = noResume; alarmStatus.noRinseback = noRinseback; alarmStatus.noEndTreatment = noEndTreatment; alarmStatus.noNewTreatment = noNewTreatment; alarmStatus.bypassDialyzer = bypassDialyzer; } /*********************************************************************//** * @brief * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm * 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; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) } } /*********************************************************************//** * @brief * The getPublishAlarmStatusInterval function gets the alarm status * publication interval. * @details * Inputs : alarmStatusPublishInterval * Outputs : none * @return the current alarm status publication interval (in ms). *************************************************************************/ U32 getPublishAlarmStatusInterval( void ) { U32 result = alarmStatusPublishInterval.data; if ( OVERRIDE_KEY == alarmStatusPublishInterval.override ) { result = alarmStatusPublishInterval.ovData; } return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetAlarmStatusPublishIntervalOverride function overrides the * alarm status publish interval. * @details * Inputs : none * Outputs : alarmStatusPublishInterval * @param value override blood flow data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAlarmStatusPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_GENERAL_INTERVAL; result = TRUE; alarmStatusPublishInterval.ovData = intvl; alarmStatusPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetAlarmStatusPublishIntervalOverride function resets the override * of the alarm status publish interval. * @details * Inputs : none * Outputs : alarmStatusPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetAlarmStatusPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; alarmStatusPublishInterval.override = OVERRIDE_RESET; alarmStatusPublishInterval.ovData = alarmStatusPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetAlarmStateOverride function overrides the state of the * alarm active state for a given alarm with the alarm management with * a given active state. * @details * Inputs : none * Outputs : alarm activated or cleared * @param alarmID ID of alarm to activate or clear * @param value override state for the given alarm ID (1=activate, 0=clear) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAlarmStateOverride( U32 alarmID, U32 state ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { if ( TRUE == state ) { activateAlarmNoData( (ALARM_ID_T)alarmID ); } else { clearAlarm( (ALARM_ID_T)alarmID ); } result = TRUE; } } return result; } /*********************************************************************//** * @brief * The testResetAlarmStateOverride function resets the override of the * state of the active state for a given alarm with the alarm management. * @details * Inputs : none * Outputs : alarm cleared * @param alarmID ID of alarm to clear * @return TRUE if alarm clear successful, FALSE if not *************************************************************************/ BOOL testResetAlarmStateOverride( U32 alarmID ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; clearAlarm( (ALARM_ID_T)alarmID ); } } return result; } /*********************************************************************//** * @brief * The testSetAlarmStartOverride function overrides the start time * for a given alarm with the alarm management with a given start time. * @details * Inputs : none * Outputs : alarmStartedAt[] * @param alarmID ID of alarm to override start time for * @param value override time since start (in ms) for the given alarm ID * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetAlarmStartOverride( U32 alarmID, U32 value ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { U32 tim = getMSTimerCount(); if ( tim > value ) { result = TRUE; alarmStartedAt[ alarmID ].ovData = ( tim - value ); alarmStartedAt[ alarmID ].override = OVERRIDE_KEY; } } } return result; } /*********************************************************************//** * @brief * The testResetAlarmStartOverride function resets the override of the * start time for a given alarm with the alarm management. * @details * Inputs : none * Outputs : alarmStartedAt[] * @param alarmID ID of alarm to reset override of start time for * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetAlarmStartOverride( U32 alarmID ) { BOOL result = FALSE; if ( alarmID < NUM_OF_ALARM_IDS ) { if ( TRUE == isTestingActivated() ) { result = TRUE; alarmStartedAt[ alarmID ].override = OVERRIDE_RESET; alarmStartedAt[ alarmID ].ovData = alarmStartedAt[ alarmID ].ovInitData; } } return result; } /**@}*/