Index: firmware/App/HDCommon.h =================================================================== diff -u -r933a18d740285e70be9d00696ed0f5a5381bc8e4 -rd13534495f6b9ea565c38ea88e9bc658c3325636 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 933a18d740285e70be9d00696ed0f5a5381bc8e4) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision d13534495f6b9ea565c38ea88e9bc658c3325636) @@ -37,6 +37,7 @@ // #define BREADBOARD_TARGET 1 // old breadboard system build - no longer used? // #define SIMULATE_UI 1 // build w/o requirement that UI be there // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes alarm lamp pins for task timing +// #define DISABLE_ALARM_AUDIO 1 // disable alarm audio #define SKIP_POST 1 // skip POST tests - all pass // #define LIMITED_NVDATA_CRC_CHECKS 1 // only perform POST CRC checks on nv-data records that are implemented so far #define DISABLE_AIR_TRAP_LEVELING 1 // disable air trap level control Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rc672f41061bcd500d6593655641cb27ce3ae58fc -rd13534495f6b9ea565c38ea88e9bc658c3325636 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision c672f41061bcd500d6593655641cb27ce3ae58fc) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision d13534495f6b9ea565c38ea88e9bc658c3325636) @@ -38,7 +38,9 @@ #define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. -#define SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. +#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. // *** 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 ) ]; @@ -50,7 +52,15 @@ #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. +#define CLR_BACKUP_AUDIO_ENABLE() {mibspiREG3->PC3 &= ~BACKUP_AUDIO_ENABLE_SPI3_PORT_MASK;} ///< Macro to disable backup alarm audio. + +/// 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; // ********** private data ********** @@ -61,12 +71,14 @@ /// table - current state of each alarm condition (detected or cleared) static BOOL alarmIsDetected[ 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. +static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; +/// Record for the current composite alarm status. +static COMP_ALARM_STATUS_T alarmStatus; + +/// FIFO - first activated or highest sub-rank alarm in each alarm priority category. +static ALARM_PRIORITY_RANKS_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; + static U32 alarmAudioVolumeLevel = MAX_ALARM_VOLUME_LEVEL; ///< Set alarm audio volume level (0..7). // ********** private function prototypes ********** @@ -82,7 +94,7 @@ static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); -static U32 getAlarmStartTime( U32 alarmID ); +static U32 getAlarmStartTime( ALARM_ID_T alarmID ); /*********************************************************************//** * @brief @@ -112,7 +124,9 @@ // 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 alarmStatus.alarmsState = ALARM_PRIORITY_NONE; @@ -394,7 +408,7 @@ alarmStartedAt[ alarm ].data = 0; // clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ ALARM_TABLE[ alarm ].alarmPriority ] == alarm ) + if ( alarmPriorityFIFO[ ALARM_TABLE[ alarm ].alarmPriority ].alarmID == alarm ) { resetAlarmPriorityFIFO( ALARM_TABLE[ alarm ].alarmPriority ); } @@ -487,7 +501,7 @@ * @param alarmID ID of alarm to check * @return The start time stamp of given alarm ID *************************************************************************/ -static U32 getAlarmStartTime( U32 alarmID ) +static U32 getAlarmStartTime( ALARM_ID_T alarmID ) { U32 result = 0; @@ -524,17 +538,39 @@ ALARM_ID_T a; BOOL faultsActive = 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] ) { - ALARM_PRIORITY_T almPriority = ALARM_TABLE[ a ].alarmPriority; - if ( ALARM_ID_NO_ALARM == alarmPriorityFIFO[ almPriority ] ) - { - alarmPriorityFIFO[ almPriority ] = a; - } - highestPriority = MAX( almPriority, highestPriority ); + ALARM_PRIORITY_T almPriority = ALARM_TABLE[ a ].alarmPriority; + U32 subRank = ALARM_TABLE[ a ].alarmSubRank; + U32 msSinceTriggered = getAlarmStartTime( a ); + + // see if this alarm is higher rank than highest active alarm in this priority category so far + if ( subRank <= alarmPriorityFIFO[ a ].subRank ) + { + // if sub-rank is a tie, see which alarm was triggered first + if ( subRank == alarmPriorityFIFO[ a ].subRank ) + { + if ( msSinceTriggered > alarmPriorityFIFO[ a ].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 ) { faultsActive = TRUE; @@ -544,7 +580,7 @@ // update alarm to display per highest priority FIFO alarmStatus.alarmsState = highestPriority; - alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ]; + alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; alarmStatus.systemFault = faultsActive; } @@ -625,7 +661,9 @@ { if ( alarmStatus.alarmsState < NUM_OF_ALARM_PRIORITIES ) { +#ifndef DISABLE_ALARM_AUDIO setAlarmAudioState( alarmStatus.alarmsState, alarmAudioVolumeLevel ); +#endif } else { @@ -799,7 +837,9 @@ // 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 { @@ -965,7 +1005,7 @@ alarmIsActive[ a ] = FALSE; alarmStartedAt[ a ].data = 0; // clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ ALARM_TABLE[ a ].alarmPriority ] == a ) + if ( alarmPriorityFIFO[ ALARM_TABLE[ a ].alarmPriority ].alarmID == a ) { resetAlarmPriorityFIFO( ALARM_TABLE[ a ].alarmPriority ); } Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rc672f41061bcd500d6593655641cb27ce3ae58fc -rd13534495f6b9ea565c38ea88e9bc658c3325636 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision c672f41061bcd500d6593655641cb27ce3ae58fc) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision d13534495f6b9ea565c38ea88e9bc658c3325636) @@ -1073,7 +1073,14 @@ } else { + U08 audioCmd = (U08)ALARM_PRIORITY_HIGH; + + // set alarm audio to high priority, max volume for safety since s/w seems to be having trouble setting audio correctly + audioCmd |= ( (U08)MAX_ALARM_VOLUME_LEVEL << 2 ); + fpgaActuatorSetPoints.AlarmControl = audioCmd; + // s/w fault to indicate issue w/ s/w SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_FPGA_INVALID_ALARM_AUDIO_PARAM, volumeLevel ) + } }