Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -rfbdff223ca110491c6f7776669fa46ac5fc56da4 -r12cb82342073207c23708afaa64b25f83f2cdfed --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision fbdff223ca110491c6f7776669fa46ac5fc56da4) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 12cb82342073207c23708afaa64b25f83f2cdfed) @@ -38,7 +38,8 @@ #define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. #define MAX_LOAD_CELL_CHANGE_G 70.0 ///< Maximum delta between new load cell sample and its small moving average (in g). -#define MAX_ACTIVE_LOAD_CELL_CHANGE_G 30.0 ///< Maximum delta between new load cell sample and its small moving average (in g) when associated reservoir is active in treatment. +#define MAX_ACTIVE_LOAD_CELL_CHANGE_G 30.0 ///< Maximum delta between new load cell sample and its small moving average (in g) when associated reservoir is active in treatment. +#define LOAD_CELL_CHANGE_PERSISTENCE 3 ///< Excessive load cell acceleration must persist for 3 samples (@ 10 Hz) to trigger alarm. /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States @@ -84,14 +85,16 @@ static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; // load cell filtering data -/// holds load cell samples for small load cell moving average +/// Holds load cell samples for small load cell moving average. static F32 smLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_SMALL_LOAD_CELL_AVG ]; -static U32 smLoadCellReadingsIdx = 0; ///< index for next sample in small load cell rolling average sample array -static F32 smLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< rolling total - used to calc small load cell moving average -/// holds load cell samples for large load cell moving average +static U32 smLoadCellReadingsIdx = 0; ///< Index for next sample in small load cell rolling average sample array. +static F32 smLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc small load cell moving average. +/// Holds load cell samples for large load cell moving average. static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; -static U32 lgLoadCellReadingsIdx = 0; ///< index for next sample in large load cell rolling average sample array -static F32 lgLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< rolling total - used to calc large load cell moving average +static U32 lgLoadCellReadingsIdx = 0; ///< Index for next sample in large load cell rolling average sample array. +static F32 lgLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc large load cell moving average. +/// Persistence counters for excessive load cell acceleration alarm. +static U32 excessiveLoadCellAccelerationCtr[ NUM_OF_DG_RESERVOIRS ] = { 0, 0 }; // DG pumps data static F32 dgROPumpFlowRateMlMin = 0.0; ///< Latest RO water flow rate reported by the DG. @@ -686,11 +689,15 @@ // Trigger or clear excessive load cell acceleration condition if ( TRUE == deltaAlarmDetected ) { - SET_ALARM_WITH_2_F32_DATA( deltaAlarm, wt, smFilteredReservoirWeightInGrams[ res ] ); + if ( ++excessiveLoadCellAccelerationCtr[ res ] > LOAD_CELL_CHANGE_PERSISTENCE ) + { + SET_ALARM_WITH_2_F32_DATA( deltaAlarm, wt, smFilteredReservoirWeightInGrams[ res ] ); + } } else { - // clearAlarmCondition( deltaAlarm ); TODO - un-comment when merged with branch that has this function implemented. + excessiveLoadCellAccelerationCtr[ res ] = 0; + clearAlarmCondition( deltaAlarm ); } #endif smLoadCellReadingsTotal[ res ] -= smLoadCellReadings[ res ][ smLoadCellReadingsIdx ]; Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r34767560b0e6574c26f5b86628e12f6bdddbd760 -r12cb82342073207c23708afaa64b25f83f2cdfed --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 34767560b0e6574c26f5b86628e12f6bdddbd760) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 12cb82342073207c23708afaa64b25f83f2cdfed) @@ -56,12 +56,19 @@ static OVERRIDE_U32_T alarmStatusPublishInterval = { ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, ALARM_STATUS_PUBLISH_INTERVAL, 0 }; static U32 alarmStatusPublicationTimerCounter = 0; ///< Used to schedule alarm status publication to CAN bus. + +/// Table - current state of each alarm. +static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; +/// Table - 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). +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 alarm in each alarm priority category. +static ALARM_ID_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; -static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< table - current state of each alarm -static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< table - when alarm became active for each alarm (if active) or zero (if inactive) -static COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. -static ALARM_ID_T alarmPriorityFIFO[ NUM_OF_ALARM_PRIORITIES ]; ///< FIFO - first activated alarm in each alarm priority category. - // ********** private function prototypes ********** static void activateAlarm( ALARM_ID_T alarm ); @@ -96,6 +103,7 @@ for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { alarmIsActive[ a ] = FALSE; + alarmIsDetected[ a ] = FALSE;; alarmStartedAt[ a ].data = 0; alarmStartedAt[ a ].ovData = 0; alarmStartedAt[ a ].ovInitData = 0; @@ -281,6 +289,29 @@ #endif } +/*********************************************************************//** + * @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 ] ) + { + alarmIsDetected[ alarm ] = FALSE; + broadcastAlarmConditionCleared( alarm ); + } + } +} + /*********************************************************************//** * @brief * The clearAlarm function clears a given alarm if it is recoverable. Also Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -rbd1ef41547aab439201897e2dcc873479a468c0a -r12cb82342073207c23708afaa64b25f83f2cdfed --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision bd1ef41547aab439201897e2dcc873479a468c0a) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 12cb82342073207c23708afaa64b25f83f2cdfed) @@ -229,6 +229,7 @@ void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ); void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ); void clearAlarm( ALARM_ID_T alarm ); +void clearAlarmCondition( ALARM_ID_T alarm ); BOOL isAlarmActive( ALARM_ID_T alarm ); ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ); BOOL isAlarmRecoverable( ALARM_ID_T alarm ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rd4a90fda6c1f463633a4e7d45424acd2d2a0bce8 -r12cb82342073207c23708afaa64b25f83f2cdfed --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d4a90fda6c1f463633a4e7d45424acd2d2a0bce8) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 12cb82342073207c23708afaa64b25f83f2cdfed) @@ -825,6 +825,35 @@ return result; } +/*********************************************************************//** + * @brief + * The broadcastAlarmConditionCleared function constructs an alarm condition + * cleared msg to be broadcast and queues the msg for transmit on the + * appropriate CAN channel. + * @details Inputs: none + * @details Outputs: alarm condition cleared msg constructed and queued. + * @param alarm ID of alarm that has had its condition cleared + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastAlarmConditionCleared( U32 alarm ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_ALARM_CONDITION_CLEARED; + msg.hdr.payloadLen = sizeof( U32 ); + + memcpy( payloadPtr, &alarm, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_ALARM, ACK_REQUIRED ); + + return result; +} + /*********************************************************************//** * @brief * The broadcastBloodFlowData function constructs a blood flow data msg to Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rd4a90fda6c1f463633a4e7d45424acd2d2a0bce8 -r12cb82342073207c23708afaa64b25f83f2cdfed --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision d4a90fda6c1f463633a4e7d45424acd2d2a0bce8) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 12cb82342073207c23708afaa64b25f83f2cdfed) @@ -183,6 +183,9 @@ // MSG_ID_ALARM_TRIGGERED BOOL broadcastAlarmTriggered( U16 alarm, ALARM_DATA_T almData1, ALARM_DATA_T almData2 ); +// MSG_ID_ALARM_CONDITION_CLEARED +BOOL broadcastAlarmConditionCleared( U32 alarm ); + // MSG_ID_ALARM_CLEARED BOOL broadcastAlarmCleared( U16 alarm );