Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rc84daa1f07003427fc5cdde8f5651434478f7313 -rd81f239e0039bc025586f7dfc21cdd3d937c8744 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision c84daa1f07003427fc5cdde8f5651434478f7313) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision d81f239e0039bc025586f7dfc21cdd3d937c8744) @@ -1,274 +1,283 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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 +* @file AlarmMgmt.c * -* @author (last) Sean Nash -* @date (last) 24-Jun-2020 +* @author (last) Dara Navaei +* @date (last) 13-Jun-2022 * -* @author (original) Sean Nash -* @date (original) 07-Nov-2019 +* @author (original) Sean Nash +* @date (original) 07-Nov-2019 * ***************************************************************************/ #include "mibspi.h" -#include "AlarmLamp.h" -#include "OperationModes.h" +#define __ALARM_MGMT_C__ + +#include "AlarmLamp.h" +#include "FPGA.h" +#include "InternalADC.h" +#include "OperationModes.h" +#include "SafetyShutdown.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" - + /** * @addtogroup AlarmManagement * @{ */ // ********** private definitions ********** + +/// Interval to control lamp and audio and to publish alarm status data. +#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 ) -#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. +#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. -#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_TEMPERATURE_OUT_OF_RANGE - { 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_CRITICAL_DATA_ERROR -}; - +// *** 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 ) ]; + +// *** This declaration will cause a compiler error if ALARM_RANK_TABLE does not have same # of alarms as the Alarm_List enumeration. +U08 alarmRankTableSizeAssertion[ ( ( sizeof( ALARM_RANK_TABLE ) / sizeof( ALARM_RANK_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; + /// 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 }; +const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; -// pin assignment for backup alarm audio enable -#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 // (SPI3-CS0 - re-purposed as output GPIO) -// backup alarm audio enable/disable macros -#define SET_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 |= BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} -#define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} +/// Pin SPI3-CS0 - re-purposed as output GPIO for backup alarm audio enable. +#define BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK 0x00000001 +// 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. + +#define ALARM_AUDIO_TEST_TONE 4 ///< Alarm audio state for continuous test tone. +#define ALARM_AUDIO_CURRENT_HG_MIN_MA 20.0F ///< Minimum audio current (high gain) during test tone self-test (in mA). // TODO - Why is HG so low? S/B same as LG I think. +#define ALARM_AUDIO_CURRENT_LG_MIN_MA 60.0F ///< Minimum audio current (low gain) during test tone self-test (in mA). +#define ALARM_AUDIO_MAX_TEST_TIME_MS 1000 ///< Maximum time for audio current to reach threshold in test. +#define MAX_ALARM_AUDIO_VOLUME_INDEX (MAX_ALARM_VOLUME_LEVEL - 1 ) ///< Index for maximum alarm audio volume. +#define MIN_ALARM_AUDIO_VOLUME_INDEX 0 ///< Index for minimum alarm audio volume. + +/// Alarm priority ranking record. +typedef struct +{ + 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 +} ALARM_PRIORITY_RANKS_T; +/// Enumeration of alarm audio self-test states. +typedef enum Alarm_Lamp_Self_Test_States +{ + ALARM_AUDIO_SELF_TEST_STATE_START = 0, ///< Start state of alarm lamp self-test. + ALARM_AUDIO_SELF_TEST_STATE_PRIMARY, ///< Red state of alarm lamp self-test. + ALARM_AUDIO_SELF_TEST_STATE_COMPLETE, ///< Completed state of alarm lamp self-test. + NUM_OF_ALARM_AUDIO_SELF_TEST_STATES ///< Number of states in alarm lamp self-test. +} ALARM_AUDIO_SELF_TEST_STATE_T; + +/// Enumeration of alarm audio volume factors. +typedef enum Alarm_Audio_Volume_Factors +{ + ALARM_AUDIO_VOLUME_GAIN = 0, ///< Gain setting for alarm audio volume. + ALARM_AUDIO_VOLUME_DIVIDER, ///< Divider setting for alarm audio volume. + NUM_OF_ALARM_AUDIO_VOLUME_FACTORS ///< Number of alarm audio volume factors. +} ALARM_AUDIO_VOLUME_FACTOR_T; + +/// Lookup table to determine appropriate divider for a given alarm audio volume level. +const U08 ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[MAX_ALARM_VOLUME_LEVEL][NUM_OF_ALARM_AUDIO_VOLUME_FACTORS] = { + { 1, 0 }, + { 1, 1 }, + { 3, 1 }, + { 3, 2 }, + { 4, 2 } +}; + // ********** 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. +static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Table - current state of each alarm +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. -/// 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 ]; - +/// 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 }; +/// Interval (in task intervals) at which to publish alarm information to CAN bus. +static OVERRIDE_U32_T alarmInfoPublishInterval = { ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, 0 }; +static OVERRIDE_U32_T alarmAudioVolumeLevel = { MAX_ALARM_VOLUME_ATTENUATION, MAX_ALARM_VOLUME_ATTENUATION, MAX_ALARM_VOLUME_ATTENUATION, 0 }; + +static OVERRIDE_F32_T alarmPrimaryAudioCurrentHG = { 0.0, 0.0, 0.0, 0 }; /// Alarm audio current (high gain) measured at ADC. + +static OVERRIDE_F32_T alarmPrimaryAudioCurrentLG = { 0.0, 0.0, 0.0, 0 }; /// Alarm audio current (low gain) measured at ADC. + +static OVERRIDE_F32_T alarmBackupAudioCurrent = { 0.0, 0.0, 0.0, 0 }; /// Alarm backup audio current measured at ADC. + +static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. +static ALARM_PRIORITY_RANKS_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; ///< FIFO - first activated or highest sub-rank alarm in each alarm priority category. + +static BOOL alarmUserRecoveryActionEnabled[ NUMBER_OF_ALARM_USER_ACTIONS ]; ///< Alarm user recovery actions enabled flags. + +/// 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; + // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); - + +static void monitorAlarms( void ); static void updateAlarmsState( void ); -static void setAlarmLampAndAudio( void ); +static void setAlarmLamp( void ); +static void setAlarmAudio( void ); static void updateAlarmsSilenceStatus( void ); static void handleAlarmEscalations( void ); static void updateAlarmsFlags( void ); - + +static void clearAllRecoverableAlarms( void ); static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); -static DATA_ARRAY_GET_PROTOTYPE( U32, getAlarmStartTime, alarmID ); -static DATA_GET_PROTOTYPE( U32, getPublishAlarmStatusInterval ); +static U32 getAlarmStartTime( ALARM_ID_T alarmID ); + +static void publishAlarmInfo( void ); -/************************************************************************* - * @brief initAlarmMgmt +/*********************************************************************//** + * @brief * The initAlarmMgmt function initializes the AlarmMgmt module. - * @details - * Inputs : none - * Outputs : AlarmMgmt module initialized. - * @param none + * @details Inputs: none + * @details Outputs: AlarmMgmt module initialized. * @return none *************************************************************************/ void initAlarmMgmt( void ) { ALARM_PRIORITY_T p; - ALARM_ID_T a; + ALARM_ID_T a; - // disable backup audio + // Disable backup audio CLR_BACKUP_AUDIO_ENABLE(); - // initialize alarm states and start time stamps + // Initialize alarm states and start time stamps for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { - alarmIsActive[ a ] = FALSE; + alarmIsActive[ a ] = FALSE; + alarmIsDetected[ a ] = FALSE;; alarmStartedAt[ a ].data = 0; alarmStartedAt[ a ].ovData = 0; alarmStartedAt[ a ].ovInitData = 0; alarmStartedAt[ a ].override = OVERRIDE_RESET; } - // initialize alarm FIFOs + // Initialize alarm FIFOs for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { - alarmPriorityFIFO[ p ] = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ p ].alarmID = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ p ].subRank = LOWEST_ALARM_SUB_RANK; + alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; } - // initialize composite alarm state + // 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.alarmTop = ALARM_ID_NO_ALARM; + alarmStatus.topAlarmConditionDetected = FALSE; alarmStatus.systemFault = FALSE; - alarmStatus.stop = FALSE; + alarmStatus.stop = FALSE; + alarmStatus.lampOn = FALSE; alarmStatus.noClear = FALSE; alarmStatus.noResume = FALSE; alarmStatus.noRinseback = FALSE; - alarmStatus.noEndTreatment = FALSE; - alarmStatus.noNewTreatment = FALSE; - alarmStatus.bypassDialyzer = FALSE; + alarmStatus.noEndTreatment = FALSE; + alarmStatus.noBloodRecirc = FALSE; + alarmStatus.noDialRecirc = FALSE; + alarmStatus.ok = FALSE; + + alarmAudioTestToneRequested = FALSE; + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; } -/************************************************************************* - * @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 +/*********************************************************************//** + * @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 : larmStatusTable[], alarmTable[] - * Outputs : larmStatus - * @param none + * @details Inputs: alarmStatusTable[], ALARM_TABLE[] + * @details Outputs: alarmStatus * @return none *************************************************************************/ void execAlarmMgmt( void ) -{ +{ + monitorAlarms(); handleAlarmEscalations(); updateAlarmsState(); updateAlarmsFlags(); updateAlarmsSilenceStatus(); - setAlarmLampAndAudio(); - // publish alarm status at interval - if ( ++alarmStatusPublicationTimerCounter >= getPublishAlarmStatusInterval() ) - { + // Publish alarm status at interval + if ( ++alarmStatusPublicationTimerCounter >= getU32OverrideValue( &alarmStatusPublishInterval ) ) + { + // Lamp and audio timing sync'd with broadcast so UI can stay in sync with lamp rhythm + setAlarmLamp(); + setAlarmAudio(); broadcastAlarmStatus( alarmStatus ); alarmStatusPublicationTimerCounter = 0; } } -/************************************************************************* - * @brief activateAlarm +/*********************************************************************//** + * @brief * The activateAlarm function activates a given alarm. - * @details - * Inputs : none - * Outputs : alarmIsActive[], alarmStartedAt[] - * @param alarm : ID of alarm to activate + * @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 + // 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 + // 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 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 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 ) + // If alarm is a fault (and not in service mode), request transition to fault mode + if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) { -#ifndef RM46_EVAL_BOARD_TARGET requestNewOperationMode( MODE_FAUL ); -#endif } - // activate alarm - alarmIsActive[ alarm ] = TRUE; - alarmStartedAt[ alarm ].data = getMSTimerCount(); + // 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 @@ -277,149 +286,137 @@ } } -/************************************************************************* - * @brief activateAlarmNoData - * The activateAlarmNoData function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n +/*********************************************************************//** + * @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 - * @param alarmData : supporting data to include in alarm msg + * @details Inputs: none + * @details 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 +{ + activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA ); } -/************************************************************************* - * @brief activateAlarm1Data - * The activateAlarm1Data function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n +/*********************************************************************//** + * @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 + * @details Inputs: none + * @details 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 + activateAlarm2Data( alarm, alarmData, BLANK_ALARM_DATA ); } -/************************************************************************* - * @brief activateAlarm1Data - * The activateAlarm2Data function activates a given alarm. Also, an alarm \n - * message is broadcast to the rest of the system. This function will \n +/*********************************************************************//** + * @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 + * @details Inputs: none + * @details 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 + // Broadcast alarm and data if alarm not already active if ( FALSE == alarmIsActive[ alarm ] ) - { - broadcastAlarmTriggered( (U16)alarm, alarmData1, alarmData2 ); + { + ALARM_TRIGGERED_PAYLOAD_T data; + + data.alarm = (U32)alarm; + data.almDataType1 = (U32)alarmData1.dataType; + data.almData1 = alarmData1.data.uInt.data; + data.almDataType2 = (U32)alarmData2.dataType; + data.almData2 = alarmData2.data.uInt.data; + data.almPriority = ALARM_TABLE[ alarm ].alarmPriority; + data.almRank = ALARM_TABLE[ alarm ].alarmSubRank; + data.almClrTopOnly = ALARM_TABLE[ alarm ].alarmClearOnly; + + broadcastData( MSG_ID_ALARM_TRIGGERED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_TRIGGERED_PAYLOAD_T ) ); + // Send information for UI to log to treatment log + if ( ( TRUE == ALARM_TABLE[ alarm ].alarmTreatmentLog ) && ( MODE_TREA == getCurrentOperationMode() ) ) + { + sendTreatmentLogAlarmEventData( 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 clearAlarm - * The clearAlarm function clears a given alarm if it is recoverable. Also \n +} + +/*********************************************************************//** + * @brief + * The clearAlarmCondition function clears a given alarm's condition detected + * flag. Also an alarm message is broadcast to the rest of the system. + * @details Inputs: none + * @details Outputs: alarmIsDetected[] + * @param alarm ID of alarm to clear condition for + * @return none + *************************************************************************/ +void clearAlarmCondition( ALARM_ID_T alarm ) +{ + // Verify given alarm + if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) + { + // Clear alarm condition and broadcast alarm condition clear if not already cleared + if ( TRUE == alarmIsDetected[ alarm ] ) + { + ALARM_ID_DATA_PUBLISH_T data; + + data.alarmID = (U32)alarm; + + alarmIsDetected[ alarm ] = FALSE; + broadcastData( MSG_ID_ALARM_CONDITION_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); + } + } +} + +/*********************************************************************//** + * @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 + * @details Inputs: none + * @details Outputs: AlarmStatusTable[], alarmIsActive[], alarmStartedAt[], + * alarmIsDetected[] + * @param alarm ID of alarm to clear * @return none *************************************************************************/ void clearAlarm( ALARM_ID_T alarm ) { - // verify given 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 ) + // Verify alarm can be cleared + if ( FALSE == ALARM_TABLE[ alarm ].alarmNoClear ) { - // clear alarm and broadcast alarm clear if not already cleared + // Clear alarm and broadcast alarm clear if not already cleared if ( TRUE == alarmIsActive[ alarm ] ) - { - broadcastAlarmCleared( alarm ); - alarmIsActive[ alarm ] = FALSE; + { + ALARM_ID_DATA_PUBLISH_T data; + + data.alarmID = (U32) alarm; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); + alarmIsActive[ alarm ] = FALSE; + clearAlarmCondition( alarm ); + alarmStartedAt[ alarm ].data = 0; - // clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ alarmTable[ alarm ].alarmPriority ] == alarm ) + // Clear FIFO if this alarm was in it + if ( alarmPriorityFIFO[ ALARM_TABLE[ alarm ].alarmPriority ].alarmID == alarm ) { - resetAlarmPriorityFIFO( alarmTable[ alarm ].alarmPriority ); + resetAlarmPriorityFIFO( ALARM_TABLE[ 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 } } } @@ -429,86 +426,422 @@ } } -/************************************************************************* - * @brief isAlarmActive - * The isAlarmActive function determines whether a given alarm is currently \n +/*********************************************************************//** + * @brief + * The setAlarmUserActionEnabled function enables/disables specific alarm + * recovery user actions while in specific modes. Ack option is always + * potentially enabled - automatically enabled as appropriate by updateAlarmsFlags(). + * @details Inputs: none + * @details Outputs: + * @param action ID of user alarm recovery action to enable/disable + * @param enabled set to TRUE to enable action, FALSE to disable + * @return none + *************************************************************************/ +void setAlarmUserActionEnabled( ALARM_USER_ACTION_T action, BOOL enabled ) +{ + if ( action < NUMBER_OF_ALARM_USER_ACTIONS ) + { + alarmUserRecoveryActionEnabled[ action ] = enabled; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_USER_ACTION, (U32)action ) + } +} + +/*********************************************************************//** + * @brief + * The signalAlarmSilence function handles an alarm silence request from + * the user. + * @details Inputs: none + * @details Outputs: alarm silence status updated + * @param cmd ID of user command (1=silence, 0=cancel silence) + * @return none + *************************************************************************/ +void signalAlarmSilence( ALARM_SILENCE_CMD_T cmd ) +{ + if ( ALARM_SILENCE_CMD_START == cmd ) + { + if ( FALSE == alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenced = TRUE; + alarmStatus.alarmsSilenceStart = getMSTimerCount(); + alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS; + } + } + else + { + if ( TRUE == alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenced = FALSE; + alarmStatus.alarmsSilenceStart = 0; + alarmStatus.alarmsSilenceExpiresIn = 0; + } + } +} + +/*********************************************************************//** + * @brief + * The signalAlarmUserActionInitiated function clears all non-recoverable alarms + * and initiates selected user action. + * @details Inputs: none + * @details Outputs: + * @param action ID of user's selected action to initiate + * @return none + *************************************************************************/ +void signalAlarmUserActionInitiated( ALARM_USER_ACTION_T action ) +{ + // Validate given action + if ( action < NUMBER_OF_ALARM_USER_ACTIONS ) + { + ALARM_ID_T a = alarmStatus.alarmTop; + + if ( ALARM_USER_ACTION_ACK == action ) + { + // If user acknowledged alarm w/ clear only property, just clear that alarm + if ( TRUE == ALARM_TABLE[ a ].alarmClearOnly ) + { + clearAlarm( a ); + } + // Otherwise we must be in mode/state where ack was only option - so clear all like other options + else + { + clearAllRecoverableAlarms(); + } + } + else + { + clearAllRecoverableAlarms(); + } + } + + // Initiate user selected action + switch ( action ) + { + case ALARM_USER_ACTION_RESUME: + initiateAlarmAction( ALARM_ACTION_RESUME ); + break; + + case ALARM_USER_ACTION_RINSEBACK: + initiateAlarmAction( ALARM_ACTION_RINSEBACK ); + break; + + case ALARM_USER_ACTION_END_TREATMENT: + initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); + break; + + case ALARM_USER_ACTION_ACK: + initiateAlarmAction( ALARM_ACTION_ACK ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_ALARM_USER_ACTION, action ); + break; + } +} + +/*********************************************************************//** + * @brief + * The isAlarmActive function determines whether a given alarm is currently * active. - * @details - * Inputs : alarmIsActive[] - * Outputs : none - * @param alarmID : ID of alarm to check + * @details Inputs: alarmIsActive[] + * @details 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 isAnyAlarmActive function determines whether any alarm is currently + * active. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any alarm is active, FALSE if not + *************************************************************************/ +BOOL isAnyAlarmActive( void ) +{ + BOOL result = ( alarmStatus.alarmTop != ALARM_ID_NO_ALARM ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The isBloodRecircBlocked function determines whether any currently + * active alarm is blocking blood re-circulation. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any active alarm prevents blood re-circulation, FALSE if not + *************************************************************************/ +BOOL isBloodRecircBlocked( void ) +{ + return alarmStatus.noBloodRecirc; +} + +/*********************************************************************//** + * @brief + * The isDialysateRecircBlocked function determines whether any currently + * active alarm is blocking dialysate re-circulation. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any active alarm prevents dialysate re-circulation, FALSE if not + *************************************************************************/ +BOOL isDialysateRecircBlocked( void ) +{ + return alarmStatus.noDialRecirc; +} + +/*********************************************************************//** + * @brief + * The doesAlarmStatusIndicateStop function determines whether any currently + * active alarm has stop property. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any active alarm has stop property, FALSE if not + *************************************************************************/ +BOOL doesAlarmStatusIndicateStop( void ) +{ + return alarmStatus.stop; +} + +/*********************************************************************//** + * @brief + * The getCurrentAlarmStatePriority function determines the current alarm + * state priority (NONE, LOW, MEDIUM, or HIGH). + * @details Inputs: alarmStatus + * @details Outputs: none + * @return current alarm state priority + *************************************************************************/ +ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ) +{ + return alarmStatus.alarmsState; } + +/*********************************************************************//** + * @brief +* The isAlarmRecoverable function determines whether a given alarm is +* recoverable. +* @details Inputs: ALARM_TABLE[] +* @details Outputs: none +* @param alarm ID of alarm to check +* @return TRUE if given alarm is recoverable, FALSE if not +*************************************************************************/ +BOOL isAlarmRecoverable( ALARM_ID_T alarm ) +{ + BOOL result = ( TRUE == ALARM_TABLE[ alarm ].alarmNoClear ? FALSE : TRUE ); + + return result; +} + +/*********************************************************************//** + * @brief +* The setAlarmAudioVolume function sets the current alarm audio volume level. +* @details Inputs: none +* @details Outputs: alarmAudioVolumeLevel +* @param volumeLevel level of volume requested (1..5) +* @return none +*************************************************************************/ +void setAlarmAudioVolume( U32 volumeLevel ) +{ + BOOL accepted = FALSE; + U32 rejReason = REQUEST_REJECT_REASON_NONE; + + if ( ( volumeLevel > 0 ) && ( volumeLevel <= MAX_ALARM_VOLUME_LEVEL ) ) + { + sendTreatmentLogEventData( ALARM_AUDIO_VOLUME_CHANGED_EVENT, (F32)volumeLevel, (F32)getAlarmAudioVolume() ); + // Convert volume level to attenuation level + alarmAudioVolumeLevel.data = MAX_ALARM_VOLUME_LEVEL - volumeLevel; + accepted = TRUE; + } + else + { + rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + + // Send response to UI + sendAlarmAudioVolumeSetResponse( accepted, rejReason ); +} + +/*********************************************************************//** + * @brief +* The handleActiveAlarmListRequest function processed the active alarms list +* request from UI. +* @details Inputs: alarmIsActive[] +* @details Outputs: sent active alarms list to UI +* @return none +*************************************************************************/ +void handleActiveAlarmListRequest( void ) +{ + BOOL accepted = TRUE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + U32 activeAlarmList[ MAX_ALARM_LIST_SIZE ]; + U32 index; + U32 activeAlarmListIndex = 0; + + for ( index = 0; index < MAX_ALARM_LIST_SIZE; index++ ) + { + activeAlarmList[ index ] = ALARM_ID_NO_ALARM; + } + + if ( TRUE == isAnyAlarmActive() ) + { + for ( index = 0; index < NUM_OF_ALARM_IDS; index++ ) + { + if ( ( TRUE == isAlarmActive( ALARM_RANK_TABLE[ index ].alarmID ) ) && ( activeAlarmListIndex < MAX_ALARM_LIST_SIZE ) ) + { + activeAlarmList[ activeAlarmListIndex ] = ALARM_RANK_TABLE[ index ].alarmID; + activeAlarmListIndex++; + } + } + } + + sendActiveAlarmsList( accepted, rejReason, activeAlarmList, sizeof( activeAlarmList ) ); +} -/************************************************************************* - * @brief getAlarmStartTime +/*********************************************************************//** + * @brief * The getAlarmStartTime function gets the active state of a given alarm. - * @details - * Inputs : alarmStartedAt[] - * Outputs : none - * @param alarmID : ID of alarm to check + * @details Inputs: alarmStartedAt[] + * @details Outputs: none + * @param alarmID ID of alarm to check * @return The start time stamp of given alarm ID *************************************************************************/ -static DATA_ARRAY_GET( U32, getAlarmStartTime, alarmID, NUM_OF_ALARM_IDS-1, alarmStartedAt, 0 ) +static U32 getAlarmStartTime( ALARM_ID_T 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 monitorAlarms function monitors alarm audio current. + * @details Inputs: alarmStatusTable[] + * @details Outputs: alarmPriorityFIFO[], alarmStatus + * @return none + *************************************************************************/ +static void monitorAlarms( void ) +{ + U32 volume = getAlarmAudioVolume(); + + alarmPrimaryAudioCurrentHG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); + alarmPrimaryAudioCurrentLG.data = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); + alarmBackupAudioCurrent.data = getFPGABackupAlarmAudioCurrent(); + + // TODO - Check current vs. expected audio output + + // Publish alarm information at interval + publishAlarmInfo(); +} -/************************************************************************* - * @brief updateAlarmsState - * The updateAlarmsState function updates the alarms state and alarm to \n +/*********************************************************************//** + * @brief + * The updateAlarmsState function updates the alarms state and alarm to * display. - * @details - * Inputs : alarmStatusTable[] - * Outputs : alarmPriorityFIFO[], alarmStatus - * @param none + * @details Inputs: alarmStatusTable[] + * @details Outputs: alarmPriorityFIFO[], alarmStatus * @return none *************************************************************************/ static void updateAlarmsState( void ) { ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE; ALARM_ID_T a; - BOOL faultsActive = FALSE; + BOOL faultsActive = FALSE; + BOOL dialysateRecircBlocked = FALSE; + BOOL bloodRecircBlocked = FALSE; - // update FIFOs per active alarms table + // Update FIFOs and sub-ranks per active alarms table - for alarm ranking purposes to determine "top" alarm for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { - if ( TRUE == alarmIsActive[a] ) + if ( TRUE == alarmIsActive[ a ] ) { - ALARM_PRIORITY_T almPriority = alarmTable[ a ].alarmPriority; - if ( ALARM_ID_NO_ALARM == alarmPriorityFIFO[ almPriority ] ) + ALARM_PRIORITY_T almPriority = ALARM_TABLE[ a ].alarmPriority; + U32 subRank = ALARM_TABLE[ a ].alarmSubRank; + U32 msSinceTriggered = calcTimeSince( getAlarmStartTime( a ) ); + + // See if this alarm is higher rank than highest active alarm in this priority category so far + if ( subRank <= alarmPriorityFIFO[ almPriority ].subRank ) + { + // If sub-rank is a tie, see which alarm was triggered first + if ( subRank == alarmPriorityFIFO[ almPriority ].subRank ) + { + if ( msSinceTriggered > alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS ) + { + alarmPriorityFIFO[ almPriority ].alarmID = a; + alarmPriorityFIFO[ almPriority ].subRank = subRank; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + } + } + // Otherwise, this alarm simply outranks current candidate and wins outright + else + { + alarmPriorityFIFO[ almPriority ].alarmID = a; + alarmPriorityFIFO[ almPriority ].subRank = subRank; + alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = msSinceTriggered; + } + } + // Track highest priority alarm found so far of all priority categories + highestPriority = MAX( almPriority, highestPriority ); + // Track whether any active faults have been found so far + if ( TRUE == ALARM_TABLE[ a ].alarmIsFault ) { - alarmPriorityFIFO[ almPriority ] = a; - } - highestPriority = MAX( almPriority, highestPriority ); - if ( TRUE == alarmTable[ a ].alarmIsFault ) - { faultsActive = TRUE; + } + // Track whether any active alarms prevent dialysate re-circulation so far + if ( TRUE == ALARM_TABLE[ a ].alarmNoDialysateRecirc ) + { + dialysateRecircBlocked = TRUE; } + // Track whether any active alarms prevent blood re-circulation so far + if ( TRUE == ALARM_TABLE[ a ].alarmNoBloodRecirc ) + { + bloodRecircBlocked = TRUE; + } } } - // update alarm to display per highest priority FIFO + // Update alarm to display per highest priority FIFO alarmStatus.alarmsState = highestPriority; - alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ]; - alarmStatus.systemFault = faultsActive; + alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; + alarmStatus.topAlarmConditionDetected = alarmIsDetected[ alarmStatus.alarmTop ]; + alarmStatus.systemFault = faultsActive; + alarmStatus.noBloodRecirc = bloodRecircBlocked; + alarmStatus.noDialRecirc = dialysateRecircBlocked; } -/************************************************************************* - * @brief setAlarmLampAndAudio - * The setAlarmLampAndAudio function sets the alarm lamp and audio patterns \n - * according to the current state of alarms. - * @details - * Inputs : none - * Outputs : Alarm lamp patter set according to current alarms status. - * @param none +/*********************************************************************//** + * @brief + * The setAlarmLamp function sets the alarm lamp pattern according to the + * current state of alarms. + * @details Inputs: none + * @details Outputs: Alarm lamp patter set according to current alarms status. * @return none *************************************************************************/ -static void setAlarmLampAndAudio( void ) -{ +static void setAlarmLamp( void ) +{ + // Set alarm lamp pattern to appropriate pattern for current alarm state if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) { switch ( alarmStatus.alarmsState ) @@ -526,7 +859,7 @@ break; case ALARM_PRIORITY_HIGH: - if ( TRUE == alarmTable[ alarmStatus.alarmTop ].alarmIsFault ) + if ( TRUE == ALARM_TABLE[ alarmStatus.alarmTop ].alarmIsFault ) { requestAlarmLampPattern( LAMP_PATTERN_FAULT ); } @@ -540,53 +873,89 @@ 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; - } + } + } + + // Execute alarm lamp controller + execAlarmLamp(); + + // Set lamp on flag to match current state of alarm lamp + if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) + { + alarmStatus.lampOn = getAlarmLampOn(); + } + else + { + alarmStatus.lampOn = FALSE; } - - 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 updateAlarmsSilenceStatus +/*********************************************************************//** + * @brief + * The setAlarmAudio function sets the alarm audio pattern according to + * the current state of alarms. + * @details Inputs: none + * @details Outputs: Alarm audio patter set according to current alarms status. + * @return none + *************************************************************************/ +static void setAlarmAudio( void ) +{ + U32 volume = getAlarmAudioVolume(); + + // If audio test in progress, play test tone. + if ( TRUE == alarmAudioTestToneRequested ) + { // Play test tone at min volume + setAlarmAudioState( ALARM_AUDIO_TEST_TONE, + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[MIN_ALARM_AUDIO_VOLUME_INDEX][ALARM_AUDIO_VOLUME_GAIN], + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[MIN_ALARM_AUDIO_VOLUME_INDEX][ALARM_AUDIO_VOLUME_DIVIDER] ); + // If we're in Fault mode, ensure audio test tone request is cancelled. + if ( MODE_FAUL == getCurrentOperationMode() ) + { + alarmAudioTestToneRequested = FALSE; + } + + } + // If alarm silenced, play no alarm audio. + else if ( ( ALARM_PRIORITY_NONE == alarmStatus.alarmsState ) || ( TRUE == alarmStatus.alarmsSilenced ) ) + { + setAlarmAudioState( ALARM_PRIORITY_NONE, + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); + } + // Otherwise, play alarm audio as appropriate based on current alarm status + else + { + if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) +#ifndef _RELEASE_ + { + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ALARM_AUDIO ) != SW_CONFIG_ENABLE_VALUE ) + { + setAlarmAudioState( alarmStatus.alarmsState, + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_GAIN], + ALARM_AUDIO_DIVIDER_LOOKUP_TABLE[volume][ALARM_AUDIO_VOLUME_DIVIDER] ); + } + } + else +#endif + { + 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] ); + } + } +} + +/*********************************************************************//** + * @brief * The updateAlarmsSilenceStatus function updates the alarms silence state. - * @details - * Inputs : alarmStatus - * Outputs : alarmStatus - * @param none + * @details Inputs: alarmStatus + * @details Outputs: alarmStatus * @return none *************************************************************************/ static void updateAlarmsSilenceStatus( void ) { - // if alarms not silenced, reset alarms silence related properties + // If alarms not silenced, reset alarms silence related properties if ( TRUE != alarmStatus.alarmsSilenced ) { alarmStatus.alarmsSilenceExpiresIn = 0; @@ -604,21 +973,19 @@ { alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; } - // if alarms silence expires, end it + // If alarms silence expires, end it if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) { alarmStatus.alarmsSilenced = FALSE; } } } -/************************************************************************* - * @brief handleAlarmEscalations +/*********************************************************************//** + * @brief * The handleAlarmEscalations function handles alarm escalation. - * @details - * Inputs : none - * Outputs : none - * @param none + * @details Inputs: alarmIsActive[], ALARM_TABLE[] + * @details Outputs: alarm(s) escalated when appropriate * @return none *************************************************************************/ static void handleAlarmEscalations( void ) @@ -627,42 +994,42 @@ ALARM_ID_T nextAlarmToEscalate = ALARM_ID_NO_ALARM; ALARM_ID_T a; - // update escalations + // 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 ) + // Does active alarm escalate? + if ( ALARM_ID_NO_ALARM != ALARM_TABLE[ a ].alarmEscalatesTo ) { - S32 msRemaining = (S32)alarmTable[ a ].alarmEscalatesAfter - (S32)calcTimeSince( getAlarmStartTime( a ) ); + S32 msRemaining = (S32)ALARM_TABLE[ a ].alarmEscalatesAfter - (S32)calcTimeSince( getAlarmStartTime( a ) ); S32 secsRemaining = ( msRemaining / MS_PER_SECOND ) + 1; - // time to escalate? + // Time to escalate? if ( msRemaining <= 0 ) { - activateAlarmNoData( alarmTable[ a ].alarmEscalatesTo ); + activateAlarmNoData( ALARM_TABLE[ a ].alarmEscalatesTo ); clearAlarm( a ); } else - { // no candidates for alarm escalation yet? + { // No candidates for alarm escalation yet? if ( ALARM_ID_NO_ALARM == nextAlarmToEscalate ) { secsToEscalate = secsRemaining; nextAlarmToEscalate = a; } - // sooner candidate for alarm escalation? + // Sooner candidate for alarm escalation? else if ( secsRemaining < secsToEscalate ) { secsToEscalate = secsRemaining; nextAlarmToEscalate = a; } } - } // if alarm escalates - } // if alarm active - } // alarm table loop + } // If alarm escalates + } // If alarm active + } // Alarm table loop - // update alarm escalation properties + // Update alarm escalation properties if ( TRUE == alarmStatus.systemFault || ALARM_ID_NO_ALARM == nextAlarmToEscalate ) { alarmStatus.alarmsToEscalate = FALSE; @@ -675,14 +1042,12 @@ } } -/************************************************************************* - * @brief updateAlarmsFlags - * The updateAlarmsFlags function updates the alarms flags of the alarms \n +/*********************************************************************//** + * @brief + * The updateAlarmsFlags function updates the alarms flags of the alarms * status record. - * @details - * Inputs : none - * Outputs : none - * @param none + * @details Inputs: none + * @details Outputs: alarmStatus * @return none *************************************************************************/ static void updateAlarmsFlags( void ) @@ -693,146 +1058,315 @@ BOOL noResume = FALSE; BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; - BOOL noNewTreatment = FALSE; - BOOL bypassDialyzer = FALSE; - ALARM_ID_T a; + BOOL usrAckReq = FALSE; + BOOL noMinimize = TRUE; + HD_OP_MODE_T currentMode = getCurrentOperationMode(); + ALARM_ID_T a; - // determine alarm flags + // 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 + systemFault = ( TRUE == ALARM_TABLE[ a ].alarmIsFault ? TRUE : systemFault ); + stop = ( TRUE == ALARM_TABLE[ a ].alarmStops ? TRUE : stop ); + noClear = ( TRUE == ALARM_TABLE[ a ].alarmNoClear ? TRUE : noClear ); + // Set user alarm recovery actions allowed flags + if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ) + { + noResume = ( TRUE == ALARM_TABLE[ a ].alarmNoResume ? TRUE : noResume ); + } + else + { + noResume = TRUE; + } + if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ) + { + noRinseback = ( TRUE == ALARM_TABLE[ a ].alarmNoRinseback ? TRUE : noRinseback ); + } + else + { + noRinseback = TRUE; + } + if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_END_TREATMENT ] ) + { + noEndTreatment = ( TRUE == ALARM_TABLE[ a ].alarmNoEndTreatment ? TRUE : noEndTreatment ); + } + else + { + noEndTreatment = TRUE; + } + } // If alarm active + } // Alarm table loop + + // If top alarm condition not cleared, block resume and rinseback flags + if ( TRUE == alarmStatus.topAlarmConditionDetected ) + { + noResume = TRUE; + noRinseback = TRUE; + } + + // If top alarm has clear only property or no other user options enabled for recoverable alarm and condition cleared, set user ack flag and block other flags + if ( ( TRUE == ALARM_TABLE[ alarmStatus.alarmTop ].alarmClearOnly ) || + ( ( FALSE == alarmStatus.noClear ) && ( noResume ) && ( noRinseback ) && ( noEndTreatment ) && + ( FALSE == alarmStatus.topAlarmConditionDetected ) ) ) + { + usrAckReq = TRUE; + noResume = TRUE; + noRinseback = TRUE; + noEndTreatment = TRUE; + } + + // If in Treatment-Stop state or Fault/Service/Standby Mode, allow user to minimize the alarm window + if ( ( MODE_FAUL == currentMode ) || ( MODE_SERV == currentMode ) || ( MODE_STAN == currentMode ) || + ( ( MODE_TREA == currentMode ) && ( TREATMENT_STOP_STATE == getTreatmentState() ) ) ) + { + noMinimize = 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; + alarmStatus.ok = usrAckReq; + alarmStatus.noMinimize = noMinimize; +} + +/*********************************************************************//** + * @brief + * The clearAllRecoverableAlarms function clears all currently active + * recoverable alarms. + * @details Inputs: ALARM_TABLE[] + * @details Outputs: All currently active recoverable alarms are cleared + * @return none + *************************************************************************/ +static void clearAllRecoverableAlarms( void ) +{ + ALARM_ID_T a = alarmStatus.alarmTop; + + for ( a = ALARM_ID_HD_SOFTWARE_FAULT; a < NUM_OF_ALARM_IDS; a++ ) + { + // Is alarm recoverable? + if ( FALSE == ALARM_TABLE[ a ].alarmNoClear ) + { + clearAlarm( a ); + } + } } -/************************************************************************* - * @brief resetAlarmPriorityFIFO - * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm \n +/*********************************************************************//** + * @brief + * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm * priority. - * @details - * Inputs : none - * Outputs : alarmPriorityFIFO[] - * @param priority : priority of FIFO to reset + * @details Inputs: none + * @details Outputs: alarmPriorityFIFO[] + * @param priority priority of FIFO to reset * @return none *************************************************************************/ static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) { - // verify priority + // Verify priority if ( priority < NUM_OF_ALARM_PRIORITIES ) { - alarmPriorityFIFO[ priority ] = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ priority ].alarmID = ALARM_ID_NO_ALARM; + alarmPriorityFIFO[ priority ].subRank = LOWEST_ALARM_SUB_RANK; + alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = 0; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) } } + +/*********************************************************************//** + * @brief + * The publishAlarmInfo function publishes alarm information at the set + * interval. + * @details Inputs: + * @details Outputs: alarm information are published to CAN bus. + * @return none + *************************************************************************/ +static void publishAlarmInfo( void ) +{ + // Publish voltages monitor data on interval + if ( ++alarmInfoPublicationTimerCounter >= getU32OverrideValue( &alarmInfoPublishInterval ) ) + { + ALARM_INFO_PAYLOAD_T data; + + data.audioVolume = MAX_ALARM_VOLUME_LEVEL - getAlarmAudioVolume(); // convert back to 1..5 volume level for publication + data.audioCurrHG = getAlarmAudioPrimaryHighGainCurrent(); + data.audioCurrLG = getAlarmAudioPrimaryLowGainCurrent(); + data.backupAudioCurr = getAlarmAudioBackupCurrent(); + data.safetyShutdown = isSafetyShutdownActivated(); + + broadcastData( MSG_ID_HD_ALARM_INFORMATION, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( ALARM_INFO_PAYLOAD_T ) ); + alarmInfoPublicationTimerCounter = 0; + } +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioVolume function gets the current alarm audio volume level. + * @details Inputs: alarmAudioVolumeLevel + * @details Outputs: none + * @return the current alarm audio volume level. + *************************************************************************/ +U32 getAlarmAudioVolume( void ) +{ + U32 result = alarmAudioVolumeLevel.data; + +#ifndef _RELEASE_ + // Check the software configurations + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_ALARM_VOLUME_DEFAULT_LOW ) ) + { + result = MIN_ALARM_VOLUME_ATTENUATION; + } +#endif + + if ( OVERRIDE_KEY == alarmAudioVolumeLevel.override ) + { + result = alarmAudioVolumeLevel.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioPrimaryHighGainCurrent function gets the current alarm + * audio high gain current. + * @details Inputs: alarmPrimaryAudioCurrentHG + * @details Outputs: none + * @return the current alarm audio high gain current (in mA). + *************************************************************************/ +F32 getAlarmAudioPrimaryHighGainCurrent( void ) +{ + F32 result = alarmPrimaryAudioCurrentHG.data; + + if ( OVERRIDE_KEY == alarmPrimaryAudioCurrentHG.override ) + { + result = alarmPrimaryAudioCurrentHG.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioPrimaryLowGainCurrent function gets the current alarm + * audio low gain current. + * @details Inputs: alarmPrimaryAudioCurrentLG + * @details Outputs: none + * @return the current alarm audio low gain current (in mA). + *************************************************************************/ +F32 getAlarmAudioPrimaryLowGainCurrent( void ) +{ + F32 result = alarmPrimaryAudioCurrentLG.data; + + if ( OVERRIDE_KEY == alarmPrimaryAudioCurrentLG.override ) + { + result = alarmPrimaryAudioCurrentLG.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getAlarmAudioBackupCurrent function gets the current backup alarm + * audio current. + * @details Inputs: alarmBackupAudioCurrent + * @details Outputs: none + * @return the current backup alarm audio current (in mA). + *************************************************************************/ +F32 getAlarmAudioBackupCurrent( void ) +{ + F32 result = alarmBackupAudioCurrent.data; + + if ( OVERRIDE_KEY == alarmBackupAudioCurrent.override ) + { + result = alarmBackupAudioCurrent.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The execAlarmAudioSelfTest function outputs a test audio tone and + * measures the audio current level. + * @details Inputs: alarmAudioSelfTestState + * @details Outputs: none + * @return the current backup alarm audio current (in mA). + *************************************************************************/ +SELF_TEST_STATUS_T execAlarmAudioSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + static U32 testStartTime; + + switch ( alarmAudioSelfTestState ) + { + case ALARM_AUDIO_SELF_TEST_STATE_START: + testStartTime = getMSTimerCount(); + // Start test tone + alarmAudioTestToneRequested = TRUE; + setAlarmAudio(); + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_PRIMARY; + break; + + case ALARM_AUDIO_SELF_TEST_STATE_PRIMARY: + { + F32 almHGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_HG ); + F32 almLGCurrent = getIntADCVoltageConverted( INT_ADC_PRIMARY_ALARM_CURRENT_LG ); + + // Check if alarm audio current is sufficiently high indicating alarm tone is being output + if ( ( almHGCurrent > ALARM_AUDIO_CURRENT_HG_MIN_MA ) && + ( almLGCurrent > ALARM_AUDIO_CURRENT_LG_MIN_MA ) ) + { + alarmAudioTestToneRequested = FALSE; + result = SELF_TEST_STATUS_PASSED; + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_COMPLETE; + } + else if ( TRUE == didTimeout( testStartTime, ALARM_AUDIO_MAX_TEST_TIME_MS ) ) + { + alarmAudioTestToneRequested = FALSE; + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_ALARM_AUDIO_SELF_TEST_FAILURE, almHGCurrent, almLGCurrent ); + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_COMPLETE; + } + } + break; + + case ALARM_AUDIO_SELF_TEST_STATE_COMPLETE: + alarmAudioSelfTestState = ALARM_AUDIO_SELF_TEST_STATE_START; // Should only get here if re-starting self-tests. + break; + + default: + // TODO - s/w fault + break; + } + + return result; +} -/************************************************************************* - * @brief getPublishAlarmStatusInterval - * The getPublishAlarmStatusInterval function gets the alarm status \n - * publication interval. - * @details - * Inputs : alarmStatusPublishInterval - * Outputs : none - * @param none - * @return the current alarm status publication interval (in ms). - *************************************************************************/ -DATA_GET( U32, getPublishAlarmStatusInterval, alarmStatusPublishInterval ) -/**@}*/ - - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ -/************************************************************************* - * @brief testSetAlarmStatusPublishIntervalOverride - * The testSetAlarmStatusPublishIntervalOverride function overrides the \n - * 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 testResetAlarmStatusPublishIntervalOverride - * The testResetAlarmStatusPublishIntervalOverride function resets the override \n - * 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 \n - * alarm active state for a given alarm with the alarm management with \n + * 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) + * @details Inputs: none + * @details 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 ) @@ -841,6 +1375,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { if ( TRUE == state ) @@ -858,14 +1393,13 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief - * The testResetAlarmStateOverride function resets the override of the \n + * 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 + * @details Inputs: none + * @details Outputs: alarm cleared + * @param alarmID ID of alarm to clear * @return TRUE if alarm clear successful, FALSE if not *************************************************************************/ BOOL testResetAlarmStateOverride( U32 alarmID ) @@ -874,6 +1408,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { result = TRUE; @@ -884,15 +1419,14 @@ return result; } -/************************************************************************* - * @brief testSetAlarmStartOverride - * The testSetAlarmStartOverride function overrides the start time \n - * for a given alarm with the alarm management with a given start time. \n - * @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 +/*********************************************************************//** + * @brief + * The testSetAlarmStartOverride function overrides the start time + * for a given alarm with the alarm management with a given start time. + * @details Inputs: none + * @details 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 ) @@ -901,6 +1435,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { U32 tim = getMSTimerCount(); @@ -917,14 +1452,13 @@ return result; } -/************************************************************************* - * @brief testResetAlarmStartOverride - * The testResetAlarmStartOverride function resets the override of the \n +/*********************************************************************//** + * @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 + * @details Inputs: none + * @details 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 ) @@ -933,6 +1467,7 @@ if ( alarmID < NUM_OF_ALARM_IDS ) { + // Verify tester has logged in with HD if ( TRUE == isTestingActivated() ) { result = TRUE; @@ -942,6 +1477,328 @@ } return result; +} + +/*********************************************************************//** + * @brief + * The testClearAllAlarms function clears all active alarms, even if they + * are non-recoverable or faults. The caller of this function must provide + * the correct 32-bit key. A Dialin user must also be logged into HD. + * @details Inputs: none + * @details Outputs: alarmIsActive[], alarmStartedAt[] + * @param key 32-bit supervior alarm key required to perform this function + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testClearAllAlarms( U32 key ) +{ + BOOL result = FALSE; + + // Verify key + if ( SUPERVISOR_ALARM_KEY == key ) + { + // Verify tester has logged in with HD + if ( TRUE == isTestingActivated() ) + { + ALARM_ID_T a; + + // Clear all active alarms + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == alarmIsActive[ a ] ) + { + ALARM_ID_DATA_PUBLISH_T data; + + data.alarmID = (U32)a; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_HD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); + alarmIsActive[ a ] = FALSE; + alarmStartedAt[ a ].data = 0; + // Clear FIFO if this alarm was in it + if ( alarmPriorityFIFO[ ALARM_TABLE[ a ].alarmPriority ].alarmID == a ) + { + resetAlarmPriorityFIFO( ALARM_TABLE[ a ].alarmPriority ); + } + } + } + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmStatusPublishIntervalOverride function sets the override of the + * alarm status publication interval. + * @details Inputs: none + * @details Outputs: alarmStatusPublishInterval + * @param ms milliseconds between alarm status broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmStatusPublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / 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 publication interval. + * @details Inputs: none + * @details 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 testSetAlarmInfoPublishIntervalOverride function sets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @param ms milliseconds between alarm info broadcasts + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = ms / TASK_GENERAL_INTERVAL; + + result = TRUE; + alarmInfoPublishInterval.ovData = intvl; + alarmInfoPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmInfoPublishIntervalOverride function resets the override of the + * alarm information publication interval. + * @details Inputs: none + * @details Outputs: alarmInfoPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmInfoPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmInfoPublishInterval.override = OVERRIDE_RESET; + alarmInfoPublishInterval.ovData = alarmInfoPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetAlarmAudioVolumeLevelOverride function sets the override of the + * alarm audio volume. + * @details Inputs: none + * @details Outputs: alarmAudioVolumeLevel + * @param volume volume level (1..5) of alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetAlarmAudioVolumeLevelOverride( U32 volume ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmAudioVolumeLevel.ovData = MAX_ALARM_VOLUME_LEVEL - volume; + alarmAudioVolumeLevel.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetAlarmAudioVolumeLevelOverride function resets the override of the + * alarm audio volume. + * @details Inputs: none + * @details Outputs: alarmAudioVolumeLevel + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetAlarmAudioVolumeLevelOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmAudioVolumeLevel.override = OVERRIDE_RESET; + alarmAudioVolumeLevel.ovData = alarmAudioVolumeLevel.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetPrimaryAlarmAudioCurrentHGOverride function sets the override of the + * alarm audio current (high gain) in mA. + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentHG + * @param mA milliamps measured from high gain channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetPrimaryAlarmAudioCurrentHGOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentHG.ovData = mA; + alarmPrimaryAudioCurrentHG.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetPrimaryAlarmAudioCurrentHGOverride function resets the override of the + * alarm audio current (high gain). + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentHG + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetPrimaryAlarmAudioCurrentHGOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentHG.override = OVERRIDE_RESET; + alarmPrimaryAudioCurrentHG.ovData = alarmPrimaryAudioCurrentHG.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetPrimaryAlarmAudioCurrentLGOverride function sets the override of the + * alarm audio current (low gain) in mA. + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentLG + * @param mA milliamps measured from low gain channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetPrimaryAlarmAudioCurrentLGOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentLG.ovData = mA; + alarmPrimaryAudioCurrentLG.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetPrimaryAlarmAudioCurrentLGOverride function resets the override of the + * alarm audio current (low gain). + * @details Inputs: none + * @details Outputs: alarmPrimaryAudioCurrentLG + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetPrimaryAlarmAudioCurrentLGOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmPrimaryAudioCurrentLG.override = OVERRIDE_RESET; + alarmPrimaryAudioCurrentLG.ovData = alarmPrimaryAudioCurrentLG.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetBackupAlarmAudioCurrentOverride function sets the override of the + * alarm audio current (backup) in mA. + * @details Inputs: none + * @details Outputs: alarmBackupAudioCurrent + * @param mA milliamps measured from backup channel of primary alarm audio + * @return TRUE if override set successful, FALSE if not + *************************************************************************/ +BOOL testSetBackupAlarmAudioCurrentOverride( F32 mA ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmBackupAudioCurrent.ovData = mA; + alarmBackupAudioCurrent.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetBackupAlarmAudioCurrentOverride function resets the override of the + * alarm audio current (backup). + * @details Inputs: none + * @details Outputs: alarmBackupAudioCurrent + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetBackupAlarmAudioCurrentOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + alarmBackupAudioCurrent.override = OVERRIDE_RESET; + alarmBackupAudioCurrent.ovData = alarmBackupAudioCurrent.ovInitData; + } + + return result; } - - + +/**@}*/