Index: firmware/App/Modes/StateTxPaused.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -65,6 +65,8 @@ static void transitionToTxPausedState( TREATMENT_PAUSED_STATE_T newState ); static void publishTreatmentPausedData( void ); +static BOOL isFluidBolusPermitted( void ); + /*********************************************************************//** * @brief * The initTreatmentPaused function initializes the Treatment Paused State unit. @@ -298,11 +300,7 @@ /*********************************************************************//** * @brief * The handleTreatmentPausedFluidBolusState function handles the fluid - * bolus sub-state of the Treatment Paused state machine. Entered either - * when an alarm fires during an active bolus in a calling state, or when - * the user requests a new bolus from the paused state. - * Monitors the permitted alarm set every tick — aborts the bolus if a - * non-permitted alarm becomes active. + * bolus sub-state of the Treatment Paused state machine. * @details \b Inputs: none * @details \b Outputs: currentTxPausedState * @return next treatment paused state. @@ -311,13 +309,6 @@ { TREATMENT_PAUSED_STATE_T result = TREATMENT_PAUSED_FLUID_BOLUS_STATE; - // Monitor permitted alarms every tick - if ( ( TRUE == isFluidBolusActive() ) && ( FALSE == isBolusAllowedByActiveAlarms() ) ) - { - signalAbortFluidBolus(); - setBolusPermitted( FALSE ); - } - // Return to pre-bolus sub-state upon bolus complete or abort if ( FALSE == isFluidBolusActive() ) { @@ -332,15 +323,15 @@ * The signalPauseFluidBolusRequest function handles a fluid bolus request * while in the Treatment Paused state. Bolus request is rejected while in * Recover blood detect state. - * @details \b Inputs: currentTxPausedState + * @details \b Inputs: none * @details \b Outputs: fluidBolusRequested * @return TRUE if request is accepted, FALSE if rejected. *************************************************************************/ BOOL signalPauseTreatFluidBolusRequest( void ) { BOOL result = FALSE; - if ( TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE != currentTxPausedState ) + if ( TRUE == isFluidBolusPermitted() ) { fluidBolusRequested = TRUE; result = TRUE; @@ -351,6 +342,33 @@ /*********************************************************************//** * @brief + * The isFluidBolusPermitted function determines whether a fluid bolus + * is currently permitted or not. + * @details \b Inputs: none + * @details \b Outputs: none + * @return TRUE if bolus is permitted, FALSE otherwise. + *************************************************************************/ +static BOOL isFluidBolusPermitted( void ) +{ + BOOL result = FALSE; + BOOL isDialysateGoodToDeliver = TRUE; // TODO: replace TRUE with getDialysateGoodToDeliverStatus() when we are ready + + //TODO: Uncomment and remove the modality when tube set type logic is implemented + //if ( ( TUBE_SET_TYPE_HDF == getTubeSetType() ) + if ( TREATMENT_MODALITY_HDF == getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_MODALITY ) ) + { + result = ( TRUE == isDialysateGoodToDeliver ) ? TRUE : FALSE; + } + else + { + result = ( TRUE != isBloodRecircBlocked() ) ? TRUE : FALSE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleTreatmentPausedBloodSittingTimer function handles the no re-circ * blood timer. It should only be called when Blood is NOT circulating. * Increments and checks for warning and alarm timeouts. @@ -542,7 +560,7 @@ } // Set if bolus is permitted or not. - setBolusPermitted( isBolusAllowedByActiveAlarms() ); + setBolusPermitted( isFluidBolusPermitted() ); } /*********************************************************************//** Index: firmware/App/Services/AlarmMgmtTD.c =================================================================== diff -u -r395522dffef1348e176564925656012f529c1910 -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision 395522dffef1348e176564925656012f529c1910) +++ firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -16,68 +16,69 @@ ***************************************************************************/ #define __ALARM_MGMT_TD_C__ - -#include "mibspi.h" - + +#include "mibspi.h" + #include "AlarmMgmtTD.h" #include "Bubbles.h" #include "CpldInterface.h" +#include "FluidBolus.h" #include "Messaging.h" #include "OperationModes.h" -#include "TaskGeneral.h" -#include "Timers.h" +#include "TaskGeneral.h" +#include "Timers.h" -/** - * @addtogroup AlarmManagementTD - * @{ - */ - -// ********** private definitions ********** +/** + * @addtogroup AlarmManagementTD + * @{ + */ -/// 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 ) +// ********** 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 SUPERVISOR_ALARM_KEY 0xD2C3B4A5 ///< 32-bit key required for clear all alarms request. /// Interval (ms/task time) Alarms are blocked after the return of AC power. #define ALARM_BLOCKED_COUNT_AFTER_AC_RETURN ( 10*MS_PER_SECOND / TASK_GENERAL_INTERVAL ) - -#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. - + +#define ALARM_SILENCE_EXPIRES_IN_SECS (60) ///< Alarm silence expiration time in seconds. + #define LOWEST_ALARM_SUB_RANK 999 ///< Lowest alarm sub-rank that can be set. #define ALARM_NOT_BLOCKED 0 ///< Alarm blocked timer value that indicates no alarm block -#define MIN_TIME_BETWEEN_ALARM_ACTIONS_MS MS_PER_SECOND ///< Minimum time between user alarm actions (in ms). - -/// A blank alarm data record for alarms that do not include alarm data when triggered. -const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; - +#define MIN_TIME_BETWEEN_ALARM_ACTIONS_MS MS_PER_SECOND ///< Minimum time between user alarm actions (in ms). + +/// A blank alarm data record for alarms that do not include alarm data when triggered. +const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; + /// 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 S32 timeSinceTriggeredMS; ///< Time (in ms) since this alarm was triggered } ALARM_PRIORITY_RANKS_T; - -// ********** private data ********** - -static OVERRIDE_U32_T alarmStartedAt[ NUM_OF_ALARM_IDS ]; ///< Table - when alarm became active for each alarm (if active) or zero (if inactive) + +// ********** private data ********** + +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. +static U32 alarmInfoPublicationTimerCounter = 0; ///< Used to schedule alarm information publication to CAN bus. static U32 alarmsBlockedTimer = 0; ///< Countdown timer used to temporarily block new alarms from being initiated static U32 lastUserAlarmActionReceivedTime = 0; ///< Time of last alarm action by user received from the UI (ms timestamp). - + /// 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 COMP_ALARM_STATUS_T alarmStatus; ///< Record for the current composite alarm status. +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. @@ -86,76 +87,76 @@ static BOOL resumeBlockedByAlarmProperty; ///< Flag indicates whether treatment resumption is currently blocked by alarm property. -// ********** private function prototypes ********** - -static void activateAlarmTD( ALARM_ID_T alarm ); +// ********** private function prototypes ********** -static void monitorAlarms( void ); -static void updateAlarmsState( void ); -static void setAlarmLamp( void ); -static void updateAlarmsSilenceStatus( void ); -static void updateAlarmsFlags( void ); +static void activateAlarmTD( ALARM_ID_T alarm ); -static BOOL clearAllRecoverableAlarms( ALARM_USER_ACTION_T action ); -static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); - +static void monitorAlarms( void ); +static void updateAlarmsState( void ); +static void setAlarmLamp( void ); +static void updateAlarmsSilenceStatus( void ); +static void updateAlarmsFlags( void ); + +static BOOL clearAllRecoverableAlarms( ALARM_USER_ACTION_T action ); +static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ); + static U32 getAlarmStartTime( ALARM_ID_T alarmID ); static void publishAlarmInfo( void ); static BOOL broadcastAlarmStatus( COMP_ALARM_STATUS_T almStatus ); - -/*********************************************************************//** - * @brief - * The initAlarmMgmtTD function initializes the TD AlarmMgmt unit. - * @details \b Inputs: none - * @details \b Outputs: TD AlarmMgmt unit initialized. - * @return none - *************************************************************************/ -void initAlarmMgmtTD( void ) -{ - ALARM_PRIORITY_T p; + +/*********************************************************************//** + * @brief + * The initAlarmMgmtTD function initializes the TD AlarmMgmt unit. + * @details \b Inputs: none + * @details \b Outputs: TD AlarmMgmt unit initialized. + * @return none + *************************************************************************/ +void initAlarmMgmtTD( void ) +{ + ALARM_PRIORITY_T p; ALARM_ID_T a; ALARM_BUTTON_BLOCKER_T b; // Initialize common alarm mgmt unit - initAlarmMgmt(); - - // Initialize alarm states and start time stamps - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + initAlarmMgmt(); + + // Initialize alarm states and start time stamps + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) { - alarmStartedAt[ a ].data = 0; - alarmStartedAt[ a ].ovData = 0; - alarmStartedAt[ a ].ovInitData = 0; - alarmStartedAt[ a ].override = OVERRIDE_RESET; - } - // Initialize alarm FIFOs - for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) - { + alarmStartedAt[ a ].data = 0; + alarmStartedAt[ a ].ovData = 0; + alarmStartedAt[ a ].ovInitData = 0; + alarmStartedAt[ a ].override = OVERRIDE_RESET; + } + // Initialize alarm FIFOs + for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) + { alarmPriorityFIFO[ p ].alarmID = ALARM_ID_NO_ALARM; alarmPriorityFIFO[ p ].subRank = LOWEST_ALARM_SUB_RANK; - alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; + alarmPriorityFIFO[ p ].timeSinceTriggeredMS = 0; } // Initialize alarm button blocker flags for ( b = (ALARM_BUTTON_BLOCKER_T)0; b < NUM_OF_ALARM_BUTTON_BLOCKERS; b++ ) { alarmButtonBlockers[ b ] = FALSE; - } - // Initialize composite alarm state - alarmStatus.alarmsState = ALARM_PRIORITY_NONE; - alarmStatus.alarmsSilenced = FALSE; - alarmStatus.alarmsSilenceStart = 0; + } + // Initialize composite alarm state + alarmStatus.alarmsState = ALARM_PRIORITY_NONE; + alarmStatus.alarmsSilenced = FALSE; + alarmStatus.alarmsSilenceStart = 0; alarmStatus.alarmsSilenceExpiresIn = 0; alarmStatus.alarmTop = ALARM_ID_NO_ALARM; - alarmStatus.topAlarmConditionDetected = FALSE; - alarmStatus.systemFault = FALSE; + alarmStatus.topAlarmConditionDetected = FALSE; + alarmStatus.systemFault = FALSE; alarmStatus.stop = FALSE; - alarmStatus.lampOn = FALSE; - alarmStatus.noClear = FALSE; - alarmStatus.noResume = FALSE; - alarmStatus.noRinseback = FALSE; + alarmStatus.lampOn = FALSE; + alarmStatus.noClear = FALSE; + alarmStatus.noResume = FALSE; + alarmStatus.noRinseback = FALSE; alarmStatus.noEndTreatment = FALSE; alarmStatus.noBloodRecirc = FALSE; - alarmStatus.noDialRecirc = FALSE; + alarmStatus.noDialRecirc = FALSE; alarmStatus.ok = FALSE; alarmsBlockedTimer = 0; @@ -165,24 +166,24 @@ // Initialize alarm audio and lamp initAlarmLamp(); initAlarmAudio(); -} - -/*********************************************************************//** - * @brief - * The execAlarmMgmt function executes the TD alarm management functions to be - * done periodically. The system alarm state is updated, alarm lamp and +} + +/*********************************************************************//** + * @brief + * The execAlarmMgmt function executes the TD alarm management functions to be + * done periodically. The system alarm state is updated, alarm lamp and * audio patterns are updated, and the state of the alarm system is sent out - * to the rest of the system. - * @details \b Inputs: alarmsBlockedTimer - * @details \b Outputs: alarmsBlockedTimer - * @return none - *************************************************************************/ -void execAlarmMgmt( void ) + * to the rest of the system. + * @details \b Inputs: alarmsBlockedTimer + * @details \b Outputs: alarmsBlockedTimer + * @return none + *************************************************************************/ +void execAlarmMgmt( void ) { monitorAlarms(); - updateAlarmsState(); - updateAlarmsFlags(); - updateAlarmsSilenceStatus(); + updateAlarmsState(); + updateAlarmsFlags(); + updateAlarmsSilenceStatus(); // Publish alarm status and information at interval publishAlarmInfo(); @@ -214,9 +215,9 @@ ALARM_T props = getAlarmProperties( alarm ); ALARM_T props_top = getAlarmProperties( alarmStatus.alarmTop ); - // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm + // No need to do anything if alarm is already active, but if condition was cleared then re-trigger alarm if ( ( FALSE == isAlarmActive( alarm ) ) || - ( ( FALSE == isAlarmConditionDetected( alarm ) ) && ( FALSE == props.alarmConditionClearImmed ) ) ) + ( ( FALSE == isAlarmConditionDetected( alarm ) ) && ( FALSE == props.alarmConditionClearImmed ) ) ) { activateAlarm( alarm ); alarmStartedAt[ alarm ].data = getMSTimerCount(); @@ -231,31 +232,33 @@ if ( ALARM_ID_NO_ALARM == alarmStatus.alarmTop ) { alarmStatus.alarmTop = alarm; - } + } // If alarm stops, set that status immediately (don't wait for status update function) if ( TRUE == props.alarmStops ) { alarmStatus.stop = TRUE; + // Signal when alarm with stop property is triggered to fluid bolus + signalNewStopAlarmActivated(); } - // If alarm is a fault (and not in service mode), request transition to fault mode - if ( ( TRUE == props.alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) - { - requestNewOperationMode( MODE_FAUL ); - } + // If alarm is a fault (and not in service mode), request transition to fault mode + if ( ( TRUE == props.alarmIsFault ) && ( getCurrentOperationMode() != MODE_SERV ) ) + { + requestNewOperationMode( MODE_FAUL ); + } // If alarm has stop property, signal stop now if ( TRUE == props.alarmStops ) { initiateAlarmAction( ALARM_ACTION_STOP ); - } - } - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE1, alarm ) + } + } } -} - + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE1, alarm ) + } +} + /*********************************************************************//** * @brief * The clearAlarmTD function clears a given alarm if it is recoverable. @@ -289,51 +292,51 @@ } } -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief * The activateAlarmNoData function activates a given alarm. The alarm - * data that gets logged with this alarm will be blank. - * @details \b Inputs: none - * @details \b Outputs: Alarm is activated - * @param alarm ID of alarm to activate - * @return none - *************************************************************************/ -void activateAlarmNoData( ALARM_ID_T alarm ) + * data that gets logged with this alarm will be blank. + * @details \b Inputs: none + * @details \b Outputs: Alarm is activated + * @param alarm ID of alarm to activate + * @return none + *************************************************************************/ +void activateAlarmNoData( ALARM_ID_T alarm ) { - activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA, FALSE ); -} - -/*********************************************************************//** - * @brief + activateAlarm2Data( alarm, BLANK_ALARM_DATA, BLANK_ALARM_DATA, FALSE ); +} + +/*********************************************************************//** + * @brief * The activateAlarm1Data function activates a given alarm. The one given * alarm data will be logged with this alarm as well as a second blank data. - * @details \b Inputs: none - * @details \b Outputs: Alarm is activated - * @param alarm ID of alarm to activate - * @param alarmData First supporting data to include in alarm message - * @return none - *************************************************************************/ -void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) -{ + * @details \b Inputs: none + * @details \b Outputs: Alarm is activated + * @param alarm ID of alarm to activate + * @param alarmData First supporting data to include in alarm message + * @return none + *************************************************************************/ +void activateAlarm1Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData ) +{ activateAlarm2Data( alarm, alarmData, BLANK_ALARM_DATA, FALSE ); -} - -/*********************************************************************//** - * @brief +} + +/*********************************************************************//** + * @brief * The activateAlarm2Data function activates a given alarm. The two given * alarm data will be logged with this alarm. * @details \b Message \b Sent: MSG_ID_ALARM_TRIGGERED - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given alarm ID is invalid. - * @details \b Inputs: alarmsBlockedTimer, determines blocked alarm conditions - * @details \b Outputs: Alarm is activated - * @param alarm ID of alarm to activate - * @param alarmData1 First supporting data to include in alarm message + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given alarm ID is invalid. + * @details \b Inputs: alarmsBlockedTimer, determines blocked alarm conditions + * @details \b Outputs: Alarm is activated + * @param alarm ID of alarm to activate + * @param alarmData1 First supporting data to include in alarm message * @param alarmData2 Second supporting data to include in alarm message - * @param outside flag indicates whether alarm is originating from outside TD f/w - * @return none - *************************************************************************/ -void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2, BOOL outside ) -{ + * @param outside flag indicates whether alarm is originating from outside TD f/w + * @return none + *************************************************************************/ +void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2, BOOL outside ) +{ // Block if new alarms are occur during loss of AC power // if ( ( TRUE == getCPLDACPowerLossDetected() ) ) // { @@ -390,7 +393,7 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE2, alarm ) - } + } } /*********************************************************************//** @@ -679,7 +682,7 @@ ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ) { return alarmStatus.alarmsState; -} +} /*********************************************************************//** * @brief @@ -889,16 +892,16 @@ } } } - -/*********************************************************************//** - * @brief + +/*********************************************************************//** + * @brief * The getAlarmStartTime function gets the start time of a given alarm. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given alarm ID is invalid. - * @details \b Inputs: alarmStartedAt[] - * @details \b Outputs: none - * @param alarmID ID of alarm to get start time for - * @return The start time stamp (seconds since power up) of given alarm ID - *************************************************************************/ + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given alarm ID is invalid. + * @details \b Inputs: alarmStartedAt[] + * @details \b Outputs: none + * @param alarmID ID of alarm to get start time for + * @return The start time stamp (seconds since power up) of given alarm ID + *************************************************************************/ static U32 getAlarmStartTime( ALARM_ID_T alarmID ) { U32 result = 0; @@ -945,35 +948,35 @@ // TODO - Check current vs. expected audio output } - -/*********************************************************************//** - * @brief + +/*********************************************************************//** + * @brief * The updateAlarmsState function re-evaluates the current alarm system state * and the "top" alarm to display (highest ranking active alarm). Some of - * the properties of alarm system status are re-evaluated as well. - * @details \b Inputs: alarmStatusTable[] - * @details \b Outputs: alarmStatus, alarmPriorityFIFO[] - * @return none - *************************************************************************/ -static void updateAlarmsState( void ) -{ - ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE, p; - ALARM_ID_T a; + * the properties of alarm system status are re-evaluated as well. + * @details \b Inputs: alarmStatusTable[] + * @details \b Outputs: alarmStatus, alarmPriorityFIFO[] + * @return none + *************************************************************************/ +static void updateAlarmsState( void ) +{ + ALARM_PRIORITY_T highestPriority = ALARM_PRIORITY_NONE, p; + ALARM_ID_T a; BOOL faultsActive = FALSE; - BOOL dialysateRecircBlocked = FALSE; + BOOL dialysateRecircBlocked = FALSE; BOOL bloodRecircBlocked = FALSE; // Reset priority FIFOs so we can re-determine them below for ( p = ALARM_PRIORITY_NONE; p < NUM_OF_ALARM_PRIORITIES; p++ ) { resetAlarmPriorityFIFO( p ); } - - // 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 == isAlarmActive( a ) ) - { + + // 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 == isAlarmActive( a ) ) + { ALARM_T props = getAlarmProperties( a ); ALARM_PRIORITY_T almPriority = props.alarmPriority; U32 subRank = props.alarmSubRank; @@ -1000,87 +1003,87 @@ alarmPriorityFIFO[ almPriority ].timeSinceTriggeredMS = (S32)msSinceTriggered; } } - // Track highest priority alarm found so far of all priority categories + // 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 == props.alarmIsFault ) - { - faultsActive = TRUE; + // Track whether any active faults have been found so far + if ( TRUE == props.alarmIsFault ) + { + faultsActive = TRUE; } // Track whether any active alarms prevent dialysate re-circulation so far if ( TRUE == props.alarmNoDialysateRecirc ) { dialysateRecircBlocked = TRUE; - } + } // Track whether any active alarms prevent blood re-circulation so far if ( TRUE == props.alarmNoBloodRecirc ) { bloodRecircBlocked = TRUE; } - } - } - - // Update alarm to display per highest priority FIFO - alarmStatus.alarmsState = highestPriority; + } + } + + // Update alarm to display per highest priority FIFO + alarmStatus.alarmsState = highestPriority; alarmStatus.alarmTop = alarmPriorityFIFO[ highestPriority ].alarmID; - alarmStatus.topAlarmConditionDetected = isAlarmConditionDetected( alarmStatus.alarmTop ); + alarmStatus.topAlarmConditionDetected = isAlarmConditionDetected( alarmStatus.alarmTop ); alarmStatus.systemFault = faultsActive; alarmStatus.noBloodRecirc = bloodRecircBlocked; - alarmStatus.noDialRecirc = dialysateRecircBlocked; -} - -/*********************************************************************//** - * @brief + alarmStatus.noDialRecirc = dialysateRecircBlocked; +} + +/*********************************************************************//** + * @brief * The setAlarmLamp function sets the alarm lamp pattern according to the * current state of alarms. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if reported alarm state is invalid. - * @details \b Inputs: alarmStatus, ALARM_TABLE[] + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if reported alarm state is invalid. + * @details \b Inputs: alarmStatus, ALARM_TABLE[] * @details \b Outputs: alarmStatus, alarm lamp pattern set according to - * current alarms status. - * @return none - *************************************************************************/ -static void setAlarmLamp( void ) + * current alarms status. + * @return none + *************************************************************************/ +static void setAlarmLamp( void ) { - // Set alarm lamp pattern to appropriate pattern for current alarm state - if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) - { - switch ( alarmStatus.alarmsState ) - { - case ALARM_PRIORITY_NONE: - requestAlarmLampPattern( LAMP_PATTERN_OK ); - break; - - case ALARM_PRIORITY_LOW: - requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); - break; - - case ALARM_PRIORITY_MEDIUM: - requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); - break; - + // Set alarm lamp pattern to appropriate pattern for current alarm state + if ( getCurrentAlarmLampPattern() != LAMP_PATTERN_MANUAL ) + { + switch ( alarmStatus.alarmsState ) + { + case ALARM_PRIORITY_NONE: + requestAlarmLampPattern( LAMP_PATTERN_OK ); + break; + + case ALARM_PRIORITY_LOW: + requestAlarmLampPattern( LAMP_PATTERN_LOW_ALARM ); + break; + + case ALARM_PRIORITY_MEDIUM: + requestAlarmLampPattern( LAMP_PATTERN_MED_ALARM ); + break; + case ALARM_PRIORITY_HIGH: - { + { ALARM_T propsTop = getAlarmProperties( alarmStatus.alarmTop ); - if ( TRUE == propsTop.alarmIsFault ) - { - requestAlarmLampPattern( LAMP_PATTERN_FAULT ); - } - else - { - requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); + if ( TRUE == propsTop.alarmIsFault ) + { + requestAlarmLampPattern( LAMP_PATTERN_FAULT ); } - } - break; - - default: - requestAlarmLampPattern( LAMP_PATTERN_FAULT ); - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) - break; + else + { + requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); + } + } + break; + + default: + requestAlarmLampPattern( LAMP_PATTERN_FAULT ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_LAMP_INVALID_ALARM_STATE, alarmStatus.alarmsState ) + break; } } - // Execute alarm lamp controller + // Execute alarm lamp controller execAlarmLamp(); // Set lamp on flag to match current state of alarm lamp @@ -1091,69 +1094,69 @@ else { alarmStatus.lampOn = FALSE; - } -} - -/*********************************************************************//** - * @brief - * The updateAlarmsSilenceStatus function updates the alarms silence state. - * @details \b Inputs: alarmStatus - * @details \b Outputs: alarmStatus - * @return none - *************************************************************************/ -static void updateAlarmsSilenceStatus( void ) -{ - // If alarms not silenced, reset alarms silence related properties - if ( TRUE != alarmStatus.alarmsSilenced ) - { - alarmStatus.alarmsSilenceExpiresIn = 0; - alarmStatus.alarmsSilenceStart = 0; - } - else - { - U32 timeSinceAlarmSilenceStart = calcTimeSince( alarmStatus.alarmsSilenceStart ) / MS_PER_SECOND; - - if ( timeSinceAlarmSilenceStart >= ALARM_SILENCE_EXPIRES_IN_SECS ) - { - alarmStatus.alarmsSilenceExpiresIn = 0; - } - else - { - alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; - } - // If alarms silence expires, end it - if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) - { - alarmStatus.alarmsSilenced = FALSE; - } - } -} + } +} -/*********************************************************************//** - * @brief +/*********************************************************************//** + * @brief + * The updateAlarmsSilenceStatus function updates the alarms silence state. + * @details \b Inputs: alarmStatus + * @details \b Outputs: alarmStatus + * @return none + *************************************************************************/ +static void updateAlarmsSilenceStatus( void ) +{ + // If alarms not silenced, reset alarms silence related properties + if ( TRUE != alarmStatus.alarmsSilenced ) + { + alarmStatus.alarmsSilenceExpiresIn = 0; + alarmStatus.alarmsSilenceStart = 0; + } + else + { + U32 timeSinceAlarmSilenceStart = calcTimeSince( alarmStatus.alarmsSilenceStart ) / MS_PER_SECOND; + + if ( timeSinceAlarmSilenceStart >= ALARM_SILENCE_EXPIRES_IN_SECS ) + { + alarmStatus.alarmsSilenceExpiresIn = 0; + } + else + { + alarmStatus.alarmsSilenceExpiresIn = ALARM_SILENCE_EXPIRES_IN_SECS - timeSinceAlarmSilenceStart; + } + // If alarms silence expires, end it + if ( 0 == alarmStatus.alarmsSilenceExpiresIn ) + { + alarmStatus.alarmsSilenced = FALSE; + } + } +} + +/*********************************************************************//** + * @brief * The updateAlarmsFlags function updates the alarms status flags of the - * alarms status record. + * alarms status record. * @details \b Inputs: alarmStatus, alarmIsActive, ALARM_TABLE[], - * alarmButtonBlockers[]. alarmUserRecoveryActionEnabled[] - * @details \b Outputs: alarmStatus, alarmButtonBlockers[] - * @return none - *************************************************************************/ -static void updateAlarmsFlags( void ) -{ - BOOL systemFault = FALSE; - BOOL stop = FALSE; - BOOL noClear = FALSE; + * alarmButtonBlockers[]. alarmUserRecoveryActionEnabled[] + * @details \b Outputs: alarmStatus, alarmButtonBlockers[] + * @return none + *************************************************************************/ +static void updateAlarmsFlags( void ) +{ + BOOL systemFault = FALSE; + BOOL stop = FALSE; + BOOL noClear = FALSE; BOOL noResume = FALSE; - BOOL noResumePerAlarmPropertyOnly = FALSE; - BOOL noRinseback = FALSE; + BOOL noResumePerAlarmPropertyOnly = FALSE; + BOOL noRinseback = FALSE; BOOL noEndTreatment = FALSE; - BOOL endTxOnlyAlarmActive = FALSE; + BOOL endTxOnlyAlarmActive = FALSE; BOOL usrAckReq = FALSE; BOOL noMinimize = TRUE; TD_OP_MODE_T currentMode = getCurrentOperationMode(); ALARM_T propsTop = getAlarmProperties( alarmStatus.alarmTop ); - ALARM_ID_T a; - + ALARM_ID_T a; + // Set user alarm recovery actions allowed by state flags alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RESUME ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ? FALSE : TRUE ); alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ? FALSE : TRUE ); @@ -1163,40 +1166,40 @@ alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] = FALSE; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] = FALSE; - // Determine alarm flags - for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) - { - if ( TRUE == isAlarmActive( a ) ) - { + // Determine alarm flags + for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) + { + if ( TRUE == isAlarmActive( a ) ) + { ALARM_T props = getAlarmProperties( a ); - systemFault = ( TRUE == props.alarmIsFault ? TRUE : systemFault ); - stop = ( TRUE == props.alarmStops ? TRUE : stop ); + systemFault = ( TRUE == props.alarmIsFault ? TRUE : systemFault ); + stop = ( TRUE == props.alarmStops ? TRUE : stop ); noClear = ( TRUE == props.alarmNoClear ? TRUE : noClear ); noResumePerAlarmPropertyOnly = ( props.alarmNoResume ? TRUE : noResumePerAlarmPropertyOnly ); // Set user alarm recovery actions allowed flags alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] |= props.alarmNoResume; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] |= props.alarmNoRinseback; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] |= props.alarmNoEndTreatment; if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ) - { + { noResume = ( TRUE == props.alarmNoResume ? TRUE : noResume ); } else { noResume = TRUE; - } + } if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ) { noRinseback = ( TRUE == props.alarmNoRinseback ? TRUE : noRinseback ); } else { noRinseback = TRUE; - } + } if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_END_TREATMENT ] ) { - noEndTreatment = ( TRUE == props.alarmNoEndTreatment ? TRUE : noEndTreatment ); + noEndTreatment = ( TRUE == props.alarmNoEndTreatment ? TRUE : noEndTreatment ); } else { @@ -1208,8 +1211,8 @@ ( FALSE == props.alarmNoEndTreatment ) ) { endTxOnlyAlarmActive = TRUE; - } - } // If alarm active + } + } // If alarm active } // Alarm table loop // If top alarm condition not cleared, block resume @@ -1252,16 +1255,16 @@ 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.ok = usrAckReq; + // Set updated alarm flags + alarmStatus.systemFault = systemFault; + alarmStatus.stop = stop; + alarmStatus.noClear = noClear; + alarmStatus.noResume = noResume; + alarmStatus.noRinseback = noRinseback; + alarmStatus.noEndTreatment = noEndTreatment; + alarmStatus.ok = usrAckReq; alarmStatus.noMinimize = noMinimize; - resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; + resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; } /*********************************************************************//** @@ -1302,32 +1305,32 @@ } return result; -} - -/*********************************************************************//** - * @brief - * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm +} + +/*********************************************************************//** + * @brief + * The resetAlarmPriorityFIFO function resets a FIFO for a given alarm * priority. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given priority is invalid. - * @details \b Inputs: none - * @details \b Outputs: alarmPriorityFIFO[] - * @param priority Alarm priority associated with FIFO to reset - * @return none - *************************************************************************/ -static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) -{ - // Verify priority - if ( priority < NUM_OF_ALARM_PRIORITIES ) - { + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given priority is invalid. + * @details \b Inputs: none + * @details \b Outputs: alarmPriorityFIFO[] + * @param priority Alarm priority associated with FIFO to reset + * @return none + *************************************************************************/ +static void resetAlarmPriorityFIFO( ALARM_PRIORITY_T priority ) +{ + // Verify priority + if ( priority < NUM_OF_ALARM_PRIORITIES ) + { alarmPriorityFIFO[ priority ].alarmID = ALARM_ID_NO_ALARM; alarmPriorityFIFO[ priority ].subRank = LOWEST_ALARM_SUB_RANK; - alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = -1; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) - } -} + alarmPriorityFIFO[ priority ].timeSinceTriggeredMS = -1; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_FIFO_TO_RESET, priority ) + } +} /*********************************************************************//** * @brief @@ -1412,23 +1415,23 @@ return result; } - -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testSetAlarmStartTimeOverride function overrides the start time for a - * given alarm with a given start time. - * @details \b Inputs: msTimerCount - * @details \b Outputs: alarmStartedAt[] + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetAlarmStartTimeOverride function overrides the start time for a + * given alarm with a given start time. + * @details \b Inputs: msTimerCount + * @details \b Outputs: alarmStartedAt[] * @param message Override message from Dialin which includes an ID of * the alarm to override start time for and a number of milliseconds the * override is seeking to make the elapsed time since the given alarm was - * triggered. - * @return TRUE if override is successful, FALSE if not + * triggered. + * @return TRUE if override is successful, FALSE if not *************************************************************************/ BOOL testSetAlarmStartTimeOverride( MESSAGE_T *message ) { @@ -1467,7 +1470,7 @@ return result; } - + /*********************************************************************//** * @brief * The testClearAllAlarms function clears all active alarms, even if they Index: firmware/App/Services/StateServices/FluidBolus.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -37,8 +37,6 @@ // ********** private definitions ********** -#define NUM_OF_FLUID_BOLUS_PERMITTED_ALARMS 6U ///< Number of permitted alarms for fluid bolus from paused state. - static const U32 FLUID_BOLUS_DATA_PUB_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL); ///< Saline bolus data broadcast interval (ms/task time) count. @@ -50,35 +48,21 @@ static BOOL fluidBolusStartRequested; ///< Flag indicates a fluid bolus start has been requested by user. static BOOL fluidBolusAbortRequested; ///< Flag indicates a fluid bolus abort has been requested by user. static BOOL pubBolusPermitted; ///< Flag indicates a bolus is permitted or not to UI (used to broadcast). +static BOOL newAlarmIndicateStop; ///< Flag indicating alarm with stop property is triggered. static U32 targetBloodFlowMLPM; ///< Blood pump flow rate (mL/min) to use for current bolus delivery. static F32 totalFluidVolumeDelivered_mL; ///< Volume (mL) in total of fluid delivered so far (cumulative for all boluses including current one). static F32 bolusFluidVolumeDelivered_mL; ///< Volume (mL) of current bolus delivered so far (calculated from measured blood flow rate). static U32 bolusVolumeLastUpdateTimeStamp; ///< Time stamp for last bolus volume update. -// TODO: replace TRUE with getDialysateGoodToDeliverStatus() when we are ready -BOOL isDialysateGoodToDeliver = TRUE; ///< Flag indicating dialysate is good to deliver to the patient. - -///< Permitted alarm list-bolus allowed from paused state -static const ALARM_ID_T FLUID_BOLUS_PERMITTED_PAUSED_ALARMS[ NUM_OF_FLUID_BOLUS_PERMITTED_ALARMS ] = -{ - ALARM_ID_TD_TREATMENT_STOPPED_BY_USER, - ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH, - ALARM_ID_TD_ARTERIAL_PRESSURE_LOW, - ALARM_ID_TD_VENOUS_PRESSURE_HIGH, - ALARM_ID_TD_TMP_PRESSURE_HIGH, - ALARM_ID_TD_TMP_PRESSURE_LOW -}; - // ********** private function prototypes ********** static void updateFluidBolusVolumeDelivered( void ); static void completeBolusToCumulative( void ); static FLUID_BOLUS_STATE_T handleFluidBolusIdleState( void ); static FLUID_BOLUS_STATE_T handleFluidBolusWait4Pumps2Stop( void ); -static FLUID_BOLUS_STATE_T handleFluidBolusSalineInProgressState( void ); -static FLUID_BOLUS_STATE_T handleFluidBolusSubstituteInProgressState( void ); +static FLUID_BOLUS_STATE_T handleFluidBolusInProgressState( void ); /*********************************************************************//** * @brief @@ -89,7 +73,8 @@ * @details \b Outputs: currentFluidBolusState, currentFluidBolusMedium, * fluidBolusBroadCastTimerCtr, targetBloodFlowMLPM, totalFluidVolumeDelivered_mL, * bolusFluidVolumeDelivered_mL, fluidBolusStartRequested, - * fluidBolusAbortRequested, bolusVolumeLastUpdateTimeStamp, pubBolusPermitted + * fluidBolusAbortRequested, bolusVolumeLastUpdateTimeStamp, pubBolusPermitted, + * newAlarmIndicateStop * @return none *************************************************************************/ void initFluidBolus( void ) @@ -104,6 +89,7 @@ fluidBolusAbortRequested = FALSE; bolusVolumeLastUpdateTimeStamp = getMSTimerCount(); pubBolusPermitted = TRUE; + newAlarmIndicateStop = FALSE; } /*********************************************************************//** @@ -118,9 +104,9 @@ FLUID_BOLUS_STATE_T priorState = currentFluidBolusState; // If alarm fires while bolus is active, abort the bolus - if ( ( TRUE == doesAlarmStatusIndicateStop() ) && ( TRUE == isFluidBolusActive() ) && - ( TREATMENT_PAUSED_STATE != getTreatmentState() ) ) + if ( ( TRUE == newAlarmIndicateStop ) && ( TRUE == isFluidBolusActive() ) ) { + newAlarmIndicateStop = FALSE; signalAbortFluidBolus(); } @@ -134,14 +120,10 @@ currentFluidBolusState = handleFluidBolusWait4Pumps2Stop(); break; - case FLUID_BOLUS_SALINE_IN_PROGRESS_STATE: - currentFluidBolusState = handleFluidBolusSalineInProgressState(); + case FLUID_BOLUS_IN_PROGRESS_STATE: + currentFluidBolusState = handleFluidBolusInProgressState(); break; - case FLUID_BOLUS_SUBSITUTE_IN_PROGRESS_STATE: - currentFluidBolusState = handleFluidBolusSubstituteInProgressState(); - break; - default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_FLUID_BOLUS_STATE, currentFluidBolusState ) currentFluidBolusState = FLUID_BOLUS_IDLE_STATE; @@ -185,7 +167,9 @@ FLUID_BOLUS_MEDIUM_T medium = FLUID_BOLUS_MEDIUM_SALINE; U32 modality = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_MODALITY ); - if ( ( modality == TREATMENT_MODALITY_HDF ) ) // || ( modality == TREATMENT_MODALITY_HD ) && ( check online fluid enabled ) + //TODO: Uncomment and remove the modality when tube set type logic is implemented + //if ( ( TUBE_SET_TYPE_HDF == getTubeSetType() ) + if ( ( modality == TREATMENT_MODALITY_HDF ) ) { medium = FLUID_BOLUS_MEDIUM_SUBSTITUTE; } @@ -309,6 +293,8 @@ if ( TRUE == fluidBolusStartRequested ) { fluidBolusStartRequested = FALSE; + // Clear when alarm is triggered and can be set when new alarm is triggered. + newAlarmIndicateStop = FALSE; // Stop blood pump signalBloodPumpHardStop(); // Stop substitution pump @@ -352,90 +338,62 @@ if ( FLUID_BOLUS_MEDIUM_SALINE == currentFluidBolusMedium ) { setBloodPumpTargetFlowRate( targetBloodFlowMLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - state = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; } - else if ( TRUE == isDialysateGoodToDeliver ) + else { // set D92 flow rate cmdSubstitutionRate( (F32)targetBloodFlowMLPM ); - state = FLUID_BOLUS_SUBSITUTE_IN_PROGRESS_STATE; } - else - { - state = FLUID_BOLUS_IDLE_STATE; - } + + state = FLUID_BOLUS_IN_PROGRESS_STATE; } return state; } /*********************************************************************//** * @brief - * The handleFluidBolusSalineInProgressState function handles the saline - * in-progress state of the fluid bolus state machine. Integrates delivered - * volume from measured blood flow, fires an alarm if the saline bag is empty, - * and completes the bolus when the target volume is reached or an abort is requested. - * @details \b Inputs: bolusFluidVolumeDelivered_mL, fluidBolusAbortRequested + * The handleFluidBolusInProgressState function handles the in-progress + * state of the fluid bolus state machine. Integrates delivered volume from + * measured flow rate every tick. For saline medium, fires an alarm if the + * saline bag is empty. For substitution medium, aborts if dialysate is no + * longer good to deliver. Completes the bolus when the target volume is + * reached or an abort is requested. + * @details \b Inputs: bolusFluidVolumeDelivered_mL, fluidBolusAbortRequested, + * currentFluidBolusMedium * @details \b Outputs: fluidBolusAbortRequested * @return next fluid bolus state *************************************************************************/ -static FLUID_BOLUS_STATE_T handleFluidBolusSalineInProgressState( void ) +static FLUID_BOLUS_STATE_T handleFluidBolusInProgressState( void ) { - FLUID_BOLUS_STATE_T state = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; - F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); + FLUID_BOLUS_STATE_T state = FLUID_BOLUS_IN_PROGRESS_STATE; + F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); + BOOL isDialysateGoodToDeliver = TRUE; // TODO: replace TRUE with getDialysateGoodToDeliverStatus() when we are ready updateFluidBolusVolumeDelivered(); - // Check for empty saline bag per arterial line pressure - if ( TRUE == isSalineBagEmpty() ) + if ( FLUID_BOLUS_MEDIUM_SALINE == currentFluidBolusMedium ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_EMPTY_SALINE_BAG, getFilteredArterialPressure() ); - state = FLUID_BOLUS_IDLE_STATE; + // Check for empty saline bag per arterial line pressure + if ( TRUE == isSalineBagEmpty() ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_EMPTY_SALINE_BAG, getFilteredArterialPressure() ); + state = FLUID_BOLUS_IDLE_STATE; + } } - // Determine if bolus is complete or stopped by user - else if ( ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) ) - { - fluidBolusAbortRequested = FALSE; - state = FLUID_BOLUS_IDLE_STATE; - } else { - // No action required + if ( FALSE == isDialysateGoodToDeliver ) + { + state = FLUID_BOLUS_IDLE_STATE; + } } - // Bolus ended, stop blood pump and record delivered volume - if ( state != FLUID_BOLUS_SALINE_IN_PROGRESS_STATE ) + // Bolus ended or target volume reached or aborted, stop delivery and record volume. + if ( ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) || ( FLUID_BOLUS_IDLE_STATE == state ) ) { - signalBloodPumpHardStop(); - completeBolusToCumulative(); - } - - return state; -} - -/*********************************************************************//** - * @brief - * The handleFluidBolusSubstituteInProgressState function handles the - * substitute in-progress state state of the fluid bolus state machine. - * Integrates delivered volume from measured blood flow. Monitors dialysate - * readiness every tick, aborts if dialysate is no longer good to deliver. - * Completes the bolus when target is reached or an abort is requested. - * @details \b Inputs: bolusFluidVolumeDelivered_mL, fluidBolusAbortRequested - * @details \b Outputs: fluidBolusAbortRequested, - * totalFluidVolumeDelivered_mL via completeBolusToCumulative() - * @return next fluid bolus state. - *************************************************************************/ -static FLUID_BOLUS_STATE_T handleFluidBolusSubstituteInProgressState( void ) -{ - FLUID_BOLUS_STATE_T state = FLUID_BOLUS_SUBSITUTE_IN_PROGRESS_STATE; - F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); - - updateFluidBolusVolumeDelivered(); - - // Check for dialysate, target volume delivered or abort from user - if ( ( FALSE == isDialysateGoodToDeliver ) || ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) ) - { fluidBolusAbortRequested = FALSE; + signalBloodPumpHardStop(); cmdSubstitutionRate( 0.0F ); completeBolusToCumulative(); state = FLUID_BOLUS_IDLE_STATE; @@ -476,58 +434,6 @@ } /*********************************************************************//** - * @brief - * The isBolusAllowedByActiveAlarms function checks whether all - * currently active alarms permit a fluid bolus from the paused state. - * For saline medium, a non-permitted alarm blocks the bolus only if it is - * TD source. For substitute medium, any non-permitted alarm blocks the bolus. - * @details \b Inputs: FLUID_BOLUS_PERMITTED_PAUSED_ALARMS[], currentFluidBolusMedium - * @details \b Outputs: none - * @return TRUE if all active alarms permit the bolus, FALSE otherwise. - *************************************************************************/ -BOOL isBolusAllowedByActiveAlarms( void ) -{ - U32 alarm; - U32 permittedIndex; - BOOL permitted = FALSE; - BOOL result = TRUE; - - for ( alarm = 0; alarm < NUM_OF_ALARM_IDS; alarm++ ) - { - if ( TRUE == isAlarmActive( alarm ) ) - { - for ( permittedIndex = 0; permittedIndex < NUM_OF_FLUID_BOLUS_PERMITTED_ALARMS; permittedIndex++ ) - { - if ( FLUID_BOLUS_PERMITTED_PAUSED_ALARMS[ permittedIndex ] == alarm ) - { - permitted = TRUE; - break; - } - } - - if ( FALSE == permitted ) - { - if ( FLUID_BOLUS_MEDIUM_SALINE == currentFluidBolusMedium ) - { - if ( ALM_SRC_TD == getAlarmSource( alarm ) ) - { - result = FALSE; - break; - } - } - else - { - result = FALSE; - break; - } - } - } - } - - return result; -} - -/*********************************************************************//** * @brief * The handleFluidBolusRequest function handles the UI fluid bolus request. * @details \b Message \b Sent: MSG_ID_TD_FLUID_BOLUS_RESPONSE @@ -553,18 +459,6 @@ // TD Fluid Bolus Additional Bolus Prevention rejReason = REQUEST_REJECT_REASON_FLUID_BOLUS_IN_PROGRESS; } - else if ( TREATMENT_PAUSED_STATE == getTreatmentState() ) - { - if ( ( TRUE == isBolusAllowedByActiveAlarms() ) ) - { - result = signalPauseTreatFluidBolusRequest(); - rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; - } - else - { - rejReason = REQUEST_REJECT_REASON_ALARM_IS_ACTIVE; - } - } else { // Route to whichever calling state is currently active @@ -580,6 +474,11 @@ rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; break; + case TREATMENT_PAUSED_STATE: + result = signalPauseTreatFluidBolusRequest(); + rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; + break; + // case TREATMENT_HDF_STATE: // result = signalHdfFluidBolusRequest(); // rejReason = ( result == TRUE ) ? REQUEST_REJECT_REASON_NONE : REQUEST_REJECT_REASON_INVALID_TREATMENT_SUB_STATE; @@ -632,4 +531,17 @@ return result; } +/*********************************************************************//** + * @brief + * The signalNewStopAlarmActivated function is called by the alarm system + * when an alarm with the stop property is activated. + * @details \b Inputs: none + * @details \b Outputs: newAlarmIndicateStop + * @return none + *************************************************************************/ +void signalNewStopAlarmActivated( void ) +{ + newAlarmIndicateStop = TRUE; +} + /**@}*/ Index: firmware/App/Services/StateServices/FluidBolus.h =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/StateServices/FluidBolus.h (.../FluidBolus.h) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/StateServices/FluidBolus.h (.../FluidBolus.h) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -52,7 +52,7 @@ } FLUID_BOLUS_DATA_PAYLOAD_T; #pragma pack(pop) -// ********** public definitions ********** +// ********** public function prototypes ********** void initFluidBolus( void ); void publishFluidBolusData( void ); @@ -68,7 +68,7 @@ F32 getTotalFluidBolusVolumeDelivered( void ); BOOL handleFluidBolusRequest( MESSAGE_T *message ); -BOOL isBolusAllowedByActiveAlarms( void ); +void signalNewStopAlarmActivated( void ); /**@}*/ Index: firmware/App/Services/StateServices/TubeSetAutoEject.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/StateServices/TubeSetAutoEject.c (.../TubeSetAutoEject.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/StateServices/TubeSetAutoEject.c (.../TubeSetAutoEject.c) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -124,8 +124,8 @@ if ( previousAutoEjectState != currentAutoEjectState ) { - previousAutoEjectState = currentAutoEjectState; SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousAutoEjectState, currentAutoEjectState ); + previousAutoEjectState = currentAutoEjectState; } } Index: firmware/App/Services/StateServices/TubeSetInstall.c =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -49,6 +49,8 @@ static TUBE_SET_INSTALL_STATE_T previousInstallState; ///< Previous tube set install sub-state static TUBE_SET_INSTALL_STATE_T currentInstallState; ///< Current tubing set install sub-state +static TUBE_SET_TYPE_T currentTubeSetType; ///< Current installed tube set type + // ********** private function prototypes ********** static TUBE_SET_INSTALL_STATE_T handleAwaitTubesetConfirmationState( void ); ///< Handle Await Tubset Install Confirmation sub-state @@ -73,6 +75,7 @@ bloodPumpTimerCounter = 0; bpLastHome = TRUE; bpLeftHomeTimerCounter = 0; + currentTubeSetType = TUBE_SET_TYPE_HD; // TODO: Call setTubeSetType() when barcode scanning is implemented. } /*********************************************************************//** @@ -115,8 +118,8 @@ if ( previousInstallState != currentInstallState ) { - previousInstallState = currentInstallState; SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousInstallState, currentInstallState ); + previousInstallState = currentInstallState; } } @@ -332,4 +335,29 @@ return result; } +/*********************************************************************//** + * @brief + * The setTubeSetType function sets the current installed tube set type. + * @details \b Inputs: none + * @details \b Outputs: currentTubeSetType + * @param type Tube set type determined from barcode scan. + * @return none + *************************************************************************/ +void setTubeSetType( TUBE_SET_TYPE_T type ) +{ + currentTubeSetType = type; +} + +/*********************************************************************//** + * @brief + * The getTubeSetType function returns the current installed tube set type. + * @details \b Inputs: currentTubeSetType + * @details \b Outputs: none + * @return Current installed tube set type. + *************************************************************************/ +TUBE_SET_TYPE_T getTubeSetType( void ) +{ + return currentTubeSetType; +} + /**@}*/ Index: firmware/App/Services/StateServices/TubeSetInstall.h =================================================================== diff -u -r9cc543b1c2508280767573e20eddd94e68be1fb5 -r0b025cea0b0f290ea44714a8fae6d71ea05088b9 --- firmware/App/Services/StateServices/TubeSetInstall.h (.../TubeSetInstall.h) (revision 9cc543b1c2508280767573e20eddd94e68be1fb5) +++ firmware/App/Services/StateServices/TubeSetInstall.h (.../TubeSetInstall.h) (revision 0b025cea0b0f290ea44714a8fae6d71ea05088b9) @@ -32,7 +32,7 @@ // ********** public definitions ********** -/// Enumeration of Tube Set install sub-states. +///< Enumeration of Tube Set install sub-states. enum Tube_Set_Install_States { TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION = 0, // Awaiting user confirmation that tubeset is placed. @@ -42,7 +42,7 @@ TUBE_SET_INSTALL_STATE_COMPLETE, // Install state complete NUM_OF_TUBE_SET_INSTALL_SUB_STATES, // Num of install sub-states }; -/// Type for tube set install states enumeration +///< Type for tube set install states enumeration typedef enum Tube_Set_Install_States TUBE_SET_INSTALL_STATE_T; // ********** public function prototypes ********** @@ -53,6 +53,9 @@ BOOL isTubeSetInstallComplete( void ); // Returns True once auto-load finished successfully BOOL handleAutoLoadRequest( MESSAGE_T *message ); // Handle UI auto-load confirmation request +void setTubeSetType( TUBE_SET_TYPE_T type ); // Set the current installed tube set type +TUBE_SET_TYPE_T getTubeSetType( void ); // Get the current installed tube set type + /**@}*/ #endif