Index: firmware/App/Services/AlarmMgmtTD.c =================================================================== diff -u -ra0d405d152c0f451ebf3c25e3c2cfa49a4db17cd -r395522dffef1348e176564925656012f529c1910 --- firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision a0d405d152c0f451ebf3c25e3c2cfa49a4db17cd) +++ firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision 395522dffef1348e176564925656012f529c1910) @@ -1,23 +1,26 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 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 AlarmMgmtTD.c * -* @author (last) Sean -* @date (last) 30-Jul-2024 +* @author (last) Dara Navaei +* @date (last) 01-Aug-2025 * -* @author (original) Sean -* @date (original) 30-Jul-2024 +* @author (original) Sean Nash +* @date (original) 01-Aug-2024 * ***************************************************************************/ + +#define __ALARM_MGMT_TD_C__ #include "mibspi.h" #include "AlarmMgmtTD.h" +#include "Bubbles.h" #include "CpldInterface.h" #include "Messaging.h" #include "OperationModes.h" @@ -99,6 +102,7 @@ static U32 getAlarmStartTime( ALARM_ID_T alarmID ); static void publishAlarmInfo( void ); +static BOOL broadcastAlarmStatus( COMP_ALARM_STATUS_T almStatus ); /*********************************************************************//** * @brief @@ -141,8 +145,6 @@ alarmStatus.alarmsSilenced = FALSE; alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; - alarmStatus.alarmsEscalatesIn = 0; - alarmStatus.alarmsToEscalate = FALSE; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; alarmStatus.topAlarmConditionDetected = FALSE; alarmStatus.systemFault = FALSE; @@ -681,46 +683,153 @@ /*********************************************************************//** * @brief + * The handleAlarmTriggered function handles the triggered alarm from the other + * stacks. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message Pointer to the triggered alarm message + * @return TRUE if message handled successfully, FALSE if not + *************************************************************************/ +BOOL handleAlarmTriggered( MESSAGE_T *message ) +{ + BOOL status = FALSE; + + if ( message->hdr.payloadLen == sizeof( ALARM_TRIGGERED_PAYLOAD_T ) ) + { + ALARM_TRIGGERED_PAYLOAD_T payload; + U08 *payloadPtr = message->payload; + + memcpy( &payload, payloadPtr, sizeof( ALARM_TRIGGERED_PAYLOAD_T ) ); + + if ( (ALARM_ID_T)(payload.alarm) < NUM_OF_ALARM_IDS ) + { + ALARM_DATA_T alm1, alm2; + + status = TRUE; + alm1.dataType = (ALARM_DATA_TYPES_T)(payload.almDataType1); + alm1.data.uInt.data = payload.almData1; + alm2.dataType = (ALARM_DATA_TYPES_T)(payload.almDataType2); + alm2.data.uInt.data = payload.almData2; + activateAlarm2Data( (ALARM_ID_T)(payload.alarm), alm1, alm2, TRUE ); + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The handleAlarmConditionCleared function handles the cleared alarm from + * the other stacks. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message Pointer to the cleared alarm message + * @return TRUE if message handled successfully, FALSE if not + *************************************************************************/ +BOOL handleAlarmConditionCleared( MESSAGE_T *message ) +{ + BOOL status = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + U08 *payloadPtr = message->payload; + U32 alarmID; + + memcpy( &alarmID, payloadPtr, sizeof( U32 ) ); + + if ( (ALARM_ID_T)alarmID < NUM_OF_ALARM_IDS ) + { + clearAlarmCondition( (ALARM_ID_T)alarmID ); + status = TRUE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The handleAlarmUserAction function handles the alarm user action that is + * received from the UI. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message Pointer to the user action request message + * @return TRUE if message handled successfully, FALSE if not + *************************************************************************/ +BOOL handleAlarmUserAction( MESSAGE_T *message ) +{ + BOOL status = FALSE; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + U08 *payloadPtr = message->payload; + U32 action; + + memcpy( &action, payloadPtr, sizeof( U32 ) ); + + if ( (ALARM_USER_ACTION_T)action < NUMBER_OF_ALARM_USER_ACTIONS ) + { + signalAlarmUserActionInitiated( (ALARM_USER_ACTION_T)action ); + status = TRUE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief * The handleActiveAlarmListRequest function handles the active alarms list * request from UI. * @note Active alarm list is sorted by rank and is limited to maximum 10 alarm * entries. * @details \b Message \b Sent: MSG_ID_TD_ACTIVE_ALARMS_LIST_REQUEST_RESPONSE * @details \b Inputs: alarmStatus, alarmIsActive[], ALARM_RANK_TABLE[] -* @details \b Outputs: sent active alarms list to UI -* @return none +* @details \b Outputs: none +* @return TRUE if request handled successfully, FALSE if not *************************************************************************/ -void handleActiveAlarmListRequest( void ) +BOOL handleActiveAlarmListRequest( MESSAGE_T *message ) { ACTIVE_ALARM_LIST_RESPONSE_PAYLOAD_T activeAlarmPayload; + BOOL result; U32 index; U32 activeAlarmListIndex = 0; - activeAlarmPayload.accepted = TRUE; - activeAlarmPayload.rejectionReason = (U32)REQUEST_REJECT_REASON_NONE; - // Blank alarm list initially for ( index = 0; index < MAX_ALARM_LIST_SIZE; index++ ) { activeAlarmPayload.activeAlarmList[ index ] = ALARM_ID_NO_ALARM; } - // Fill alarm list from (up to) 10 highest priority active alarms - if ( TRUE == isAnyAlarmActive() ) + if ( 0 == message->hdr.payloadLen ) { - for ( index = 0; index < NUM_OF_ALARM_IDS; index++ ) - { - ALARM_RANK_T ranks = getAlarmRank( index ); + activeAlarmPayload.accepted = TRUE; + activeAlarmPayload.rejectionReason = (U32)REQUEST_REJECT_REASON_NONE; - if ( ( TRUE == isAlarmActive( ranks.alarmID ) ) && ( activeAlarmListIndex < MAX_ALARM_LIST_SIZE ) ) + // Fill alarm list from (up to) 10 highest priority active alarms + if ( TRUE == isAnyAlarmActive() ) + { + for ( index = 0; index < NUM_OF_ALARM_IDS; index++ ) { - activeAlarmPayload.activeAlarmList[ activeAlarmListIndex ] = ranks.alarmID; - activeAlarmListIndex++; + ALARM_RANK_T ranks = getAlarmRank( index ); + + if ( ( TRUE == isAlarmActive( ranks.alarmID ) ) && ( activeAlarmListIndex < MAX_ALARM_LIST_SIZE ) ) + { + activeAlarmPayload.activeAlarmList[ activeAlarmListIndex ] = ranks.alarmID; + activeAlarmListIndex++; + } } } } + else + { + activeAlarmPayload.accepted = FALSE; + activeAlarmPayload.rejectionReason = (U32)REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + } -// TODO sendActiveAlarmsList( activeAlarmPayload ); + result = sendMessage( MSG_ID_TD_ACTIVE_ALARMS_LIST_REQUEST_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&activeAlarmPayload), sizeof( ACTIVE_ALARM_LIST_RESPONSE_PAYLOAD_T ) ); + + return result; } /*********************************************************************//** @@ -759,6 +868,27 @@ } } } + +/*********************************************************************//** + * @brief + * The handleAutoResumeAlarm function handles the auto resume status of an alarm. + * @details \b Inputs: alarmStatus + * @details \b Outputs: none + * @param alarmID ID of alarm to be handled. + * @return none + *************************************************************************/ +void handleAutoResumeAlarm( ALARM_ID_T alarm ) +{ + ALARM_T props = getAlarmProperties( alarm ); + + if ( TRUE == props.alarmAutoResume ) + { + if ( ( alarm == alarmStatus.alarmTop ) && ( FALSE == alarmStatus.noResume ) ) + { + signalAlarmUserActionInitiated( ALARM_USER_ACTION_RESUME ); + } + } +} /*********************************************************************//** * @brief @@ -808,7 +938,7 @@ if ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == getConfirmationRequestStatus( GENERIC_CONFIRM_ID_TREATMENT_END ) ) { // To avoid raising repeated alarm before reaching end treatment -// setVenousBubbleDetectionEnabled( FALSE ); + setVenousBubbleDetectionEnabled( H18_BBLD, FALSE ); clearAllRecoverableAlarms( ALARM_USER_ACTION_END_TREATMENT ); initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); } @@ -1218,7 +1348,7 @@ // Lamp and audio timing sync'd with alarm status broadcast so UI/lamp/audio can stay in sync setAlarmLamp(); setAlarmAudio(); -// broadcastAlarmStatus( alarmStatus ); + broadcastAlarmStatus( alarmStatus ); alarmStatusPublicationTimerCounter = 0; } @@ -1240,11 +1370,48 @@ data.uiAlarmButtonBlocks[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ]; data.uiAlarmButtonBlocks[ ALARM_BUTTON_STATE_BLOCK_END_TREATMENT ] = (U08)alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_END_TREATMENT ]; -// broadcastData( MSG_ID_TD_ALARM_INFORMATION_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( ALARM_INFO_PAYLOAD_T ) ); + broadcastData( MSG_ID_TD_ALARM_INFORMATION_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( ALARM_INFO_PAYLOAD_T ) ); alarmInfoPublicationTimerCounter = 0; } } +/*********************************************************************//** + * @brief + * The broadcastAlarmStatus function constructs an alarm status msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details \b Inputs: none + * @details \b Outputs: alarm status msg constructed and queued. + * @param almStatus alarm status record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +static BOOL broadcastAlarmStatus( COMP_ALARM_STATUS_T almStatus ) +{ + BOOL result; + ALARM_COMP_STATUS_PAYLOAD_T payload; + + payload.alarmState = (U32)almStatus.alarmsState; + payload.alarmTop = (U32)almStatus.alarmTop; + payload.silenceExpiresIn = almStatus.alarmsSilenceExpiresIn; + + payload.alarmsFlags = ( almStatus.systemFault ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_SYSTEM_FAULT) : 0 ); + payload.alarmsFlags |= ( almStatus.stop ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_STOP) : 0 ); + payload.alarmsFlags |= ( almStatus.noClear ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_CLEAR) : 0 ); + payload.alarmsFlags |= ( almStatus.noResume ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_RESUME) : 0 ); + payload.alarmsFlags |= ( almStatus.noRinseback ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_RINSEBACK) : 0 ); + payload.alarmsFlags |= ( almStatus.noEndTreatment ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_END_TREATMENT) : 0 ); + payload.alarmsFlags |= ( almStatus.ok ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_OK_BUTTON_ONLY) : 0 ); + payload.alarmsFlags |= ( almStatus.alarmsSilenced ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_ALARMS_SILENCED) : 0 ); + payload.alarmsFlags |= ( almStatus.lampOn ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_LAMP_ON) : 0 ); + payload.alarmsFlags |= ( almStatus.noBloodRecirc ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_BLOOD_RECIRC) : 0 ); + payload.alarmsFlags |= ( almStatus.noDialRecirc ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_DIALYSATE_RECIRC) : 0 ); + payload.alarmsFlags |= ( almStatus.noMinimize ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_MINIMIZE) : 0 ); + payload.alarmsFlags |= ( almStatus.topAlarmConditionDetected ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_TOP_CONDITION) : 0 ); + + result = broadcastData( MSG_ID_ALARM_STATUS_DATA, COMM_BUFFER_OUT_CAN_TD_ALARM, (U08*)&payload, sizeof( ALARM_COMP_STATUS_PAYLOAD_T ) ); + + return result; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS @@ -1253,7 +1420,7 @@ /*********************************************************************//** * @brief - * The testSetAlarmStartOverride function overrides the start time for a + * The testSetAlarmStartTimeOverride function overrides the start time for a * given alarm with a given start time. * @details \b Inputs: msTimerCount * @details \b Outputs: alarmStartedAt[] @@ -1263,7 +1430,7 @@ * triggered. * @return TRUE if override is successful, FALSE if not *************************************************************************/ -BOOL testSetAlarmStartOverride( MESSAGE_T *message ) +BOOL testSetAlarmStartTimeOverride( MESSAGE_T *message ) { BOOL result = FALSE; TEST_OVERRIDE_ARRAY_PAYLOAD_T override; @@ -1309,45 +1476,53 @@ * @details \b Message \b Sent: MSG_ID_ALARM_CLEARED for each active alarm. * @details \b Inputs: none * @details \b Outputs: alarmIsActive[], alarmStartedAt[] - * @param key A 32-bit supervisor alarm key required to perform this function + * @param message Pointer to a clear all alarms message which contains a + * 32-bit supervisor alarm key required to perform this function * @return TRUE if command was successful, FALSE if rejected *************************************************************************/ -BOOL testClearAllAlarms( U32 key ) +BOOL testClearAllAlarms( MESSAGE_T *message ) { BOOL result = FALSE; + U32 key; - // Verify key - if ( SUPERVISOR_ALARM_KEY == key ) + // Verify tester has logged in with TD + if ( TRUE == isTestingActivated() ) { - // Verify tester has logged in with HD - if ( TRUE == isTestingActivated() ) + // Verify payload length + if ( sizeof(U32) == message->hdr.payloadLen ) { - ALARM_ID_T a; + memcpy( &key, message->payload, sizeof(U32) ); - // clear the flags when Dialin clears alarms - resumeBlockedByAlarmProperty = FALSE; - - // Clear all active alarms - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + // Verify key + if ( SUPERVISOR_ALARM_KEY == key ) { - if ( TRUE == isAlarmActive( a ) ) - { - ALARM_T props = getAlarmProperties( a ); - ALARM_ID_DATA_PUBLISH_T data; + ALARM_ID_T a; - data.alarmID = (U32)a; + // clear the flags when Dialin clears alarms + resumeBlockedByAlarmProperty = FALSE; - broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_TD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); - setAlarmActive( a , FALSE ); - alarmStartedAt[ a ].data = 0; - // Clear FIFO if this alarm was in it - if ( alarmPriorityFIFO[ props.alarmPriority ].alarmID == a ) + // Clear all active alarms + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == isAlarmActive( a ) ) { - resetAlarmPriorityFIFO( props.alarmPriority ); + ALARM_T props = getAlarmProperties( a ); + ALARM_ID_DATA_PUBLISH_T data; + + data.alarmID = (U32)a; + + broadcastData( MSG_ID_ALARM_CLEARED, COMM_BUFFER_OUT_CAN_TD_ALARM, (U08*)&data, sizeof( ALARM_ID_DATA_PUBLISH_T ) ); + setAlarmActive( a , FALSE ); + alarmStartedAt[ a ].data = 0; + // Clear FIFO if this alarm was in it + if ( alarmPriorityFIFO[ props.alarmPriority ].alarmID == a ) + { + resetAlarmPriorityFIFO( props.alarmPriority ); + } } } + result = TRUE; } - result = TRUE; } } @@ -1356,96 +1531,36 @@ /*********************************************************************//** * @brief - * The testSetAlarmStatusPublishIntervalOverride function sets the override - * of the alarm status publication interval. + * The testAlarmStatusPublishIntervalOverride function overrides the interval + * at which the TD alarm status data is published. * @details \b Inputs: none * @details \b Outputs: alarmStatusPublishInterval - * @param ms Number of milliseconds between alarm status broadcasts - * @return TRUE if override set is successful, FALSE if not + * @param message Override message from Dialin which includes the interval + * (in ms) to override the alarm status broadcast interval to. + * @return TRUE if override request is successful, FALSE if not *************************************************************************/ -BOOL testSetAlarmStatusPublishIntervalOverride( U32 ms ) +BOOL testAlarmStatusPublishIntervalOverride( MESSAGE_T *message ) { - BOOL result = FALSE; + BOOL result = u32BroadcastIntervalOverride( message, &alarmStatusPublishInterval, TASK_GENERAL_INTERVAL ); - 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. + * The testAlarmInfoPublishIntervalOverride function overrides the interval + * at which the TD alarm information is published. * @details \b Inputs: none - * @details \b Outputs: alarmStatusPublishInterval - * @return TRUE if override reset is 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 \b Inputs: none * @details \b Outputs: alarmInfoPublishInterval - * @param ms Number of milliseconds between alarm info broadcasts - * @return TRUE if override set is successful, FALSE if not + * @param message Override message from Dialin which includes the interval + * (in ms) to override the alarm information broadcast interval to. + * @return TRUE if override request is successful, FALSE if not *************************************************************************/ -BOOL testSetAlarmInfoPublishIntervalOverride( U32 ms ) +BOOL testAlarmInfoPublishIntervalOverride( MESSAGE_T *message ) { - BOOL result = FALSE; + BOOL result = u32BroadcastIntervalOverride( message, &alarmInfoPublishInterval, TASK_GENERAL_INTERVAL ); - 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 \b Inputs: none - * @details \b Outputs: alarmInfoPublishInterval - * @return TRUE if override reset is 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; -} - /**@}*/