Index: firmware/App/Controllers/AirPump.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file AirPump.c * * @author (last) Varshini Nagabooshanam -* @date (last) 02-Jul-2026 +* @date (last) 18-Jun-2026 * * @author (original) Sean Nash * @date (original) 19-Sep-2024 @@ -35,8 +35,6 @@ #define AIR_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Air pump data publish interval. #define DATA_PUBLISH_COUNTER_START_COUNT 13 ///< Air pump data publish start counter. #define AIR_PUMP_STALL_PERSISTENCE ( 150 / TASK_GENERAL_INTERVAL ) ///< Stall duration before alarm (150 ms) -#define AIR_PUMP_STALL_START_DELAY_MS 200 ///< Delay before evaluating stall condition -#define AIR_PUMP_STALL_START_DELAY_COUNT ( AIR_PUMP_STALL_START_DELAY_MS / TASK_GENERAL_INTERVAL ) ///< Air pump stall delay count interval #pragma pack(push, 1) /// Payload record structure for air pump test set command message payload. @@ -51,7 +49,6 @@ static AIR_PUMP_STATE_T currentAirPumpState; ///< Current air pump control state. static U08 airPumpStallCounter; ///< Air pump stall counter -static U08 airPumpStartDelayCounter; ///< Delay before evaluating air pump stall condition static U16 currentAirPumpRPM; ///< Current air pump RPM static F32 currentAirPumpPowerLevel; ///< Current air pump power level setting in % duty cycle (0..100%). static U32 airPumpDataPublicationTimerCounter; ///< Air pump data broadcast timer counter. @@ -83,7 +80,6 @@ currentAirPumpPowerLevel = AIR_PUMP_MOTOR_OFF; currentAirPumpRPM = 0; airPumpStallCounter = 0; - airPumpStartDelayCounter = 0; airPumpDataPublishInterval.data = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovData = AIR_PUMP_DATA_PUB_INTERVAL; airPumpDataPublishInterval.ovInitData = AIR_PUMP_DATA_PUB_INTERVAL; @@ -247,36 +243,22 @@ *************************************************************************/ static void checkAirPumpStallCondition( void ) { - if ( ( AIR_PUMP_STATE_ON == currentAirPumpState ) && ( currentAirPumpPowerLevel > 0 ) ) - { - // Allow RPM time to populate before evaluating stall condition - if ( airPumpStartDelayCounter < AIR_PUMP_STALL_START_DELAY_COUNT ) - { - airPumpStartDelayCounter++; - airPumpStallCounter = 0; - } - else if ( 0 == currentAirPumpRPM ) - { - // Air pump commanded on but RPM remains zero - if ( ++airPumpStallCounter >= AIR_PUMP_STALL_PERSISTENCE ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AIR_PUMP_STALL, currentAirPumpPowerLevel, currentAirPumpRPM ); - // Stop H12 air pump - setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); - } - } - else - { - // RPM detected, clear stall counter - airPumpStallCounter = 0; - } - } - else - { - // Pump is off, reset counters - airPumpStartDelayCounter = 0; - airPumpStallCounter = 0; - } + if ( ( currentAirPumpPowerLevel > 0 ) && ( currentAirPumpRPM == 0 ) ) + { + // we are commanding air pump to run but zero measured pump speed indicates it is not running + if ( ++airPumpStallCounter >= AIR_PUMP_STALL_PERSISTENCE ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_AIR_PUMP_STALL, currentAirPumpPowerLevel, currentAirPumpRPM ); + // Stop H12 air pump + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + // Stop air trap control + endAirTrapControl(); + } + } + else + { + airPumpStallCounter = 0; + } } /*********************************************************************//** Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file Valves.c * -* @author (last) Sean Nash -* @date (last) 04-May-2026 +* @author (last) Dara Navaei +* @date (last) 19-Dec-2025 * * @author (original) Sean Nash * @date (original) 24-Oct-2024 @@ -47,6 +47,21 @@ #define POS_C_FROM_ZERO_CNT VALVE_OFFEST_FROM_EDG_CNT ///< Position C from zero position in counts. #define POS_D_PARTIAL_CLOSE_FROM_ZERO_CNT ( POS_C_FROM_ZERO_CNT + 32 ) ///< Position D partial close from zero position in counts. +/// Valve controller states +typedef enum Valve_Control_States +{ + VALVE_STATE_WAIT_FOR_POST = 0, ///< Valve state wait for POST. + VALVE_STATE_RESET_VALVE, ///< Valve state reset valve. + VALVE_STATE_RESET_ENCODER, ///< Valve state reset encoder. + VALVE_STATE_ENABLE_VALVE, ///< Valve state enable valve. + VALVE_STATE_HOMING_NOT_STARTED, ///< Valve state homing not started. + VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE, ///< Valve state homing find energized edge. + VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE, ///< Valve state homing find de-energized edge. + VALVE_STATE_IDLE, ///< Valve state idle. + VALVE_STATE_IN_TRANSITION, ///< Valve state in transition. + NUM_OF_VALVE_STATES, ///< Number of valve exec states. +} VALVE_STATE_T; + /// Valve status structure typedef struct { @@ -237,31 +252,6 @@ /*********************************************************************//** * @brief - * The getValveState function returns the current state of a given valve. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given valve is invalid. - * @details \b Inputs: currentValveStates[] - * @details \b Outputs: none - * @param valve ID of valve to get current state of - * @return Current state of the given valve - *************************************************************************/ -VALVE_STATE_T getValveState( VALVE_T valve ) -{ - VALVE_STATE_T result = VALVE_STATE_HOMING_NOT_STARTED; - - if ( valve < NUM_OF_VALVES ) - { - result = currentValveStates[ valve ].controlState; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_VALVES_INVALID_VALVE2, (U32)valve ) - } - - return result; -} - -/*********************************************************************//** - * @brief * The execValvesController function executes the valves state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if a valve control state is invalid. * @details \b Inputs: currentValveStates[] Index: firmware/App/Controllers/Valves.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Controllers/Valves.h (.../Valves.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Controllers/Valves.h (.../Valves.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file Valves.h * -* @author (last) Sean Nash -* @date (last) 04-May-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 19-Jan-2026 * * @author (original) Sean Nash * @date (original) 24-Oct-2024 @@ -61,21 +61,6 @@ } TD_VALVE_DATA_T; #pragma pack(pop) -/// Valve controller states -typedef enum Valve_Control_States -{ - VALVE_STATE_WAIT_FOR_POST = 0, ///< Valve state wait for POST. - VALVE_STATE_RESET_VALVE, ///< Valve state reset valve. - VALVE_STATE_RESET_ENCODER, ///< Valve state reset encoder. - VALVE_STATE_ENABLE_VALVE, ///< Valve state enable valve. - VALVE_STATE_HOMING_NOT_STARTED, ///< Valve state homing not started. - VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE, ///< Valve state homing find energized edge. - VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE, ///< Valve state homing find de-energized edge. - VALVE_STATE_IDLE, ///< Valve state idle. - VALVE_STATE_IN_TRANSITION, ///< Valve state in transition. - NUM_OF_VALVE_STATES, ///< Number of valve exec states. -} VALVE_STATE_T; - // ********** public function prototypes ********** void initValves(void); @@ -85,7 +70,6 @@ BOOL homeValve( VALVE_T valve, BOOL force, BOOL cartridge ); BOOL setValvePosition( VALVE_T valve, VALVE_POSITION_T position ); VALVE_POSITION_T getValvePosition( VALVE_T valve ); -VALVE_STATE_T getValveState( VALVE_T valve ); BOOL testValvesDataPublishIntervalOverride( MESSAGE_T *message ); BOOL testValveSetABCCmdPosition( MESSAGE_T *message ); Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -130,8 +130,7 @@ break; case TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE: - currentPreTreatmentState = TD_PRE_TREATMENT_HEPARIN_SETUP_STATE; - setCurrentSubState((U32)currentPreTreatmentState); + currentPreTreatmentState = handleInstallState(); break; case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: @@ -353,7 +352,7 @@ BOOL paramsValid = getValidTreatParamsReceived(); BOOL paramsConfirmed = getTreatParamsConfirmed(); BOOL heparinIsPrescribed = ( ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0F ) || - ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DELIVERY_RATE ) > 0.0F ) ) ? TRUE : FALSE; + ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DELIVERY_RATE ) > 0.0F ) ); BOOL isDialysateGoodToDeliver = TRUE; // TODO replace TRUE with getDialysateGoodToDeliverStatus() when we are ready F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; F32 presUFVolumeL = 0.0F; Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file ModeStandby.c * -* @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @author (last) Arpita Srivastava +* @date (last) 18-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -27,8 +27,6 @@ #include "Switches.h" #include "SystemCommTD.h" #include "TxParams.h" -#include "Valve3Way.h" -#include "Valves.h" /** * @addtogroup TDStandbyMode @@ -44,9 +42,6 @@ static TD_STANDBY_STATE_T currentStandbyState; ///< Current state (sub-mode) of standby mode. static BOOL treatStartReqReceived; ///< Flag indicates user has requested initiation of a treatment. -static BOOL homingInitiated; ///< Flag indicates actuators have been homed. -static FLUID_TYPE_T fluidType; ///< Fluid type assigned based on user selection. -static TREATMENT_TYPE_T modality; ///< Modality from the treatment initiation. // ********** private function prototypes ********** @@ -57,16 +52,13 @@ * @brief * The initStandbyMode function initializes the Standby Mode Unit. * @details \b Inputs: none - * @details \b Outputs: Standby mode variables initialized. + * @details \b Outputs: currentStandbyState, treatStartReqReceived * @return none *************************************************************************/ void initStandbyMode( void ) { currentStandbyState = STANDBY_START_STATE; treatStartReqReceived = FALSE; - homingInitiated = FALSE; - fluidType = FLUID_TYPE_UNKNOWN; - modality = TREATMENT_MODALITY_HD_SALINE_FLUID; } /*********************************************************************//** @@ -92,22 +84,15 @@ setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); // Pumps should be off - signalBloodPumpHardStop(); +// signalBloodPumpHardStop(); // stopSyringePump(); // Set valves to default positions - set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); - set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); - if ( getValveState( H1_VALV ) < VALVE_STATE_IDLE ) - { - setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); - } - if ( getValveState( H19_VALV ) < VALVE_STATE_IDLE ) - { - setValvePosition( H19_VALV, VALVE_POSITION_A_INSERT_EJECT ); - } +// setValveAirTrap( VALVE_3WAY_COMMON_TO_CLOSED_STATE ); +// setValvePosition( H1_VALV, VALVE_POSITION_A_INSERT_EJECT ); +// setValvePosition( H19, VALVE_POSITION_A_INSERT_EJECT ); - doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode +// doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode // Request DD service record and usage information from DD // sendDGServiceRequestToDG(); @@ -168,23 +153,23 @@ // Wait for door to be closed so we can home actuators // if ( STATE_CLOSED == getSwitchState( H9_SWCH ) ) // { - // If we haven't already initiated homing of actuators, initiate now - if ( homingInitiated != TRUE ) - { - VALVE_T valve; - - // Home pumps and valves - for ( valve = FIRST_VALVE; valve < NUM_OF_VALVES; ++valve ) - { - homeValve( valve, FALSE, TRUE ); - } +// // If we haven't already initiated homing of actuators, initiate now +// if ( homingInitiated != TRUE ) +// { +// VALVE_T valve; +// +// // Home pumps and valves +// for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) +// { +// homeValve( valve, VALVE_NO_FORCE_HOME, VALVE_CARTRIDGE_MAY_BE_PRESENT ); +// } // homeBloodPump(); // homeDialInPump(); // homeDialOutPump(); // retractSyringePump(); - - homingInitiated = TRUE; - } +// +// homingInitiated = TRUE; +// } // else // { // // If homing has been initiated, wait for syringe pump to home and the verify force sensor calibration @@ -284,67 +269,17 @@ // Start treatment workflow with pretreatment mode requestNewOperationMode( MODE_PRET ); treatStartReqReceived = FALSE; - // Set fluid type - setFluidType( modality ); } return state; } /*********************************************************************//** * @brief - * The setFluidType function sets the fluid type based on the user's - * treatment selection from the home screen. - * @details \b Inputs: none - * @details \b Outputs: fluidType - * @param modality Treatment modality selected by the user on the home screen. - * @return none - *************************************************************************/ -void setFluidType( TREATMENT_TYPE_T modality ) -{ - if ( TREATMENT_MODALITY_HD_SALINE_FLUID == modality ) - { - fluidType = FLUID_TYPE_SALINE; - } - else - { - // For HDF and HD_ONLINE_FLUID - fluidType = FLUID_TYPE_SUBSTITUTE; - } -} - -/*********************************************************************//** - * @brief - * The getFluidType function returns the current fluid type assigned - * based on the user's treatment selection. - * @details \b Inputs: none - * @details \b Outputs: none - * @return Current fluid type (saline or substitution fluid). - *************************************************************************/ -FLUID_TYPE_T getFluidType( void ) -{ - return fluidType; -} - -/*********************************************************************//** - * @brief - * The getModality function returns the treatment modality received from - * the UI at treatment initiation. - * @details \b Inputs: modality - * @details \b Outputs: none - * @return Treatment modality selected by the user on the home screen. - *************************************************************************/ -TREATMENT_TYPE_T getModality( void ) -{ - return modality; -} - -/*********************************************************************//** - * @brief * The signalUserInitiateTreatment function handles user initiation of a * treatment. * @details \b Inputs: none - * @details \b Outputs: treatStartReqReceived, modality + * @details \b Outputs: treatStartReqReceived * @param message initiate/reject treatment workflow message from UI which * includes the command code (0=cancel, 1=initiate). * @return TRUE if signal accepted, FALSE if not @@ -355,27 +290,20 @@ U32 cmd = 0; TD_OP_MODE_T mode = getCurrentOperationMode(); REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; - INITIATE_TREATMENT_REQUEST_PAYLOAD_T request; UI_RESPONSE_PAYLOAD_T response; // Verify message payload length is valid - if ( sizeof( INITIATE_TREATMENT_REQUEST_PAYLOAD_T ) == message->hdr.payloadLen ) + if ( sizeof( U32 ) == message->hdr.payloadLen ) { - memcpy( &request, message->payload, sizeof( INITIATE_TREATMENT_REQUEST_PAYLOAD_T ) ); + memcpy( &cmd, message->payload, sizeof( U32 ) ); - cmd = request.command; - if ( USER_COMMAND_INITIATE == cmd ) { // Verify TD is in standby mode waiting for treatment start request if ( ( mode != MODE_STAN ) || ( STANDBY_WAIT_FOR_TREATMENT_STATE != currentStandbyState ) ) { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } - else if ( request.modality >= NUM_OF_TREATMENT_MODALITY_TYPES ) - { - rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; - } #ifndef TEST_UI_ONLY // Verify DD is communicating with HD else if ( isDDCommunicating() != TRUE ) @@ -393,8 +321,6 @@ // If request to start treatment not rejected, set flag to initiate treatment workflow result = TRUE; treatStartReqReceived = TRUE; - // Save modality to set later - modality = (TREATMENT_TYPE_T)request.modality; } } else if ( USER_COMMAND_CANCEL == cmd ) Index: firmware/App/Modes/ModeStandby.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file ModeStandby.h * -* @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @author (last) Sean Nash +* @date (last) 18-Apr-2025 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -32,13 +32,6 @@ // ********** public definitions ********** -/// Payload record structure for a treatment initiation request -typedef struct -{ - U32 command; ///< Command code (Cancel=0, Initiate=1) - U32 modality; ///< Treatment modality selected by user (ignored on cancel) -} INITIATE_TREATMENT_REQUEST_PAYLOAD_T; - // ********** public function prototypes ********** void initStandbyMode( void ); // Initialize this unit @@ -48,10 +41,6 @@ BOOL signalUserInitiateTreatment( MESSAGE_T *message ); // User has initiated/cancelled treatment workflow void signalAlarmActionToStandbyMode( ALARM_ACTION_T action ); // Execute alarm action as appropriate for Standby mode -void setFluidType( TREATMENT_TYPE_T modality ); // Set a specific fluid type -FLUID_TYPE_T getFluidType( void ); // Get a specific fluid type -TREATMENT_TYPE_T getModality( void ); // Get a specific modality - /**@}*/ #endif Index: firmware/App/Modes/StatePreTxHeparinSetup.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/StatePreTxHeparinSetup.c (.../StatePreTxHeparinSetup.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/StatePreTxHeparinSetup.c (.../StatePreTxHeparinSetup.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -438,10 +438,8 @@ /*********************************************************************//** * @brief * The handlePreTxHeparinPausedState function handles the paused state. - * @details \b Inputs: heparinSetupResumeRequested, - * interruptedPreTxHeparinSetupState - * @details \b Outputs: Next pre-treatment heparin setup state and - * syringe pump operation. + * @details \b Inputs: none + * @details \b Outputs: Next pre-treatment heparin setup state. * @return Current or next pre-treatment heparin setup state. *************************************************************************/ static PRE_TX_HEPARIN_SETUP_STATE_T handlePreTxHeparinPausedState( void ) @@ -450,32 +448,33 @@ if ( TRUE == heparinSetupResumeRequested ) { - switch ( interruptedPreTxHeparinSetupState ) + // Resume from Preload, Await Syringe Load Confirmation, or Seek by + // retracting the syringe and restarting the preload sequence. + if ( ( PRE_TX_HEPARIN_SETUP_PRELOAD_STATE == interruptedPreTxHeparinSetupState ) || + ( PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE == interruptedPreTxHeparinSetupState ) || + ( PRE_TX_HEPARIN_SETUP_SEEK_STATE == interruptedPreTxHeparinSetupState ) ) { - // If interrupted before Seek is complete, retract the syringe - // and restart the heparin setup sequence from Preload. - case PRE_TX_HEPARIN_SETUP_PRELOAD_STATE: - case PRE_TX_HEPARIN_SETUP_AWAIT_SYRINGE_LOAD_CONFIRMATION_STATE: - case PRE_TX_HEPARIN_SETUP_SEEK_STATE: - retractSyringePump(); - state = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; - break; + retractSyringePump(); + state = PRE_TX_HEPARIN_SETUP_PRELOAD_STATE; + } + else + { + // Resume from the interrupted state after the alarm is cleared. + state = interruptedPreTxHeparinSetupState; - // If interrupted after Seek is complete, resume from the - // heparin setup state that was active before the alarm. - case PRE_TX_HEPARIN_SETUP_PRIME_STATE: - case PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE: - case PRE_TX_HEPARIN_SETUP_BOLUS_STATE: - state = interruptedPreTxHeparinSetupState; - setupPreTxHeparinState( state ); - break; + switch ( state ) + { + case PRE_TX_HEPARIN_SETUP_PRIME_STATE: + case PRE_TX_HEPARIN_SETUP_OCCLUSION_CHECK_STATE: + case PRE_TX_HEPARIN_SETUP_BOLUS_STATE: + setupPreTxHeparinState( state ); + break; - // An unexpected interrupted state indicates a software fault. - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE, interruptedPreTxHeparinSetupState ); - - state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; - break; + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE, interruptedPreTxHeparinSetupState ); + state = PRE_TX_HEPARIN_SETUP_PAUSED_STATE; + break; + } } } Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file StateTxBloodPrime.c * -* @author (last) Sean Nash -* @date (last) 01-Jul-2026 +* @author (last) Praneeth Bunne +* @date (last) 03-Jun-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 09-Jan-2026 @@ -123,7 +123,7 @@ cumulativeBloodPrimeVolume_mL.data = 0.0; resetBloodPrimeFlags(); - bloodPrimeTargetVolume_mL = (F32)TUBING_BLOOD_PRIME_VOLUME_ML + (F32)( getDialyzerBloodVolume( (DIALYZER_TYPE_T)getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ) ) ); + bloodPrimeTargetVolume_mL = TUBING_BLOOD_PRIME_VOLUME_ML + (F32)( getDialyzerBloodVolume( getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ) ) ); bloodPrimeRampFlowRate_mL_min = (F32)BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN; // Calculate BP ramp step size Index: firmware/App/Modes/StateTxPaused.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file StateTxPaused.c * * @author (last) Praneeth Bunne -* @date (last) 26-Jun-2026 +* @date (last) 29-May-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -22,15 +22,13 @@ #include "DDInterface.h" #include "FluidBolus.h" #include "Messaging.h" -#include "ModeStandby.h" #include "ModeTreatment.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "RotaryValve.h" #include "StateTxPaused.h" #include "Switches.h" #include "TaskGeneral.h" -#include "TubeSetInstall.h" #include "TxParams.h" #include "Valves.h" #include "Valve3Way.h" @@ -67,8 +65,6 @@ 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. @@ -302,15 +298,26 @@ /*********************************************************************//** * @brief * The handleTreatmentPausedFluidBolusState function handles the fluid - * bolus sub-state of the Treatment Paused state machine. - * @details \b Inputs: pauseBolusResumeState + * 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. + * @details \b Inputs: none * @details \b Outputs: currentTxPausedState * @return next treatment paused state. *************************************************************************/ static TREATMENT_PAUSED_STATE_T handleTreatmentPausedFluidBolusState( void ) { 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() ) { @@ -325,15 +332,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: none + * @details \b Inputs: currentTxPausedState * @details \b Outputs: fluidBolusRequested * @return TRUE if request is accepted, FALSE if rejected. *************************************************************************/ BOOL signalPauseTreatFluidBolusRequest( void ) { BOOL result = FALSE; - if ( TRUE == isFluidBolusPermitted() ) + if ( TREATMENT_PAUSED_RECOVER_BLOOD_DETECT_STATE != currentTxPausedState ) { fluidBolusRequested = TRUE; result = TRUE; @@ -344,26 +351,6 @@ /*********************************************************************//** * @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; - - if ( FLUID_TYPE_SALINE == getFluidType() ) - { - 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. @@ -555,7 +542,7 @@ } // Set if bolus is permitted or not. - setBolusPermitted( isFluidBolusPermitted() ); + setBolusPermitted( isBolusAllowedByActiveAlarms() ); } /*********************************************************************//** Index: firmware/App/Monitors/Switches.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Monitors/Switches.c (.../Switches.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Monitors/Switches.c (.../Switches.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -153,7 +153,7 @@ { if ( getSwitchState( H9_SWCH ) != STATE_CLOSED ) { -// activateAlarmNoData( ALARM_ID_TD_CARTRIDGE_DOOR_OPENED ); + activateAlarmNoData( ALARM_ID_TD_CARTRIDGE_DOOR_OPENED ); } } Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file AlarmMgmtSWFaults.h * -* @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @author (last) Vijay Pamula +* @date (last) 12-Jun-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -197,9 +197,7 @@ SW_FAULT_ID_MODE_POST_TX_AUTO_EJECT_INVALID_STATE = 166, SW_FAULT_ID_INVALID_FLUID_BOLUS_STATE = 167, SW_FAULT_ID_PRE_TX_RECIRC_INVALID_STATE = 168, - SW_FAULT_ID_TD_VALVES_INVALID_VALVE2 = 169, - SW_FAULT_ID_INVALID_TUBE_SET_TYPE = 170, - SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE =171, + SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE =169, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/AlarmMgmtTD.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,78 +7,77 @@ * * @file AlarmMgmtTD.c * -* @author (last) Santhosh Reddy -* @date (last) 06-Jul-2026 +* @author (last) Dara Navaei +* @date (last) 01-Aug-2025 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 * ***************************************************************************/ #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 - * @{ - */ +/** + * @addtogroup AlarmManagementTD + * @{ + */ + +// ********** private definitions ********** -// ********** 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 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. @@ -87,76 +86,76 @@ static BOOL resumeBlockedByAlarmProperty; ///< Flag indicates whether treatment resumption is currently blocked by alarm property. -// ********** private function prototypes ********** +// ********** private function prototypes ********** + +static void activateAlarmTD( ALARM_ID_T alarm ); -static void activateAlarmTD( ALARM_ID_T alarm ); +static void monitorAlarms( void ); +static void updateAlarmsState( void ); +static void setAlarmLamp( void ); +static void updateAlarmsSilenceStatus( void ); +static void updateAlarmsFlags( void ); -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 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; @@ -166,24 +165,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(); @@ -215,9 +214,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(); @@ -232,33 +231,31 @@ 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. @@ -292,51 +289,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() ) ) // { @@ -393,7 +390,7 @@ else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE2, alarm ) - } + } } /*********************************************************************//** @@ -682,7 +679,7 @@ ALARM_PRIORITY_T getCurrentAlarmStatePriority( void ) { return alarmStatus.alarmsState; -} +} /*********************************************************************//** * @brief @@ -894,14 +891,14 @@ } /*********************************************************************//** - * @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; @@ -948,35 +945,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; @@ -1003,87 +1000,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 ); + if ( TRUE == propsTop.alarmIsFault ) + { + requestAlarmLampPattern( LAMP_PATTERN_FAULT ); + } + else + { + requestAlarmLampPattern( LAMP_PATTERN_HIGH_ALARM ); } - 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; + } + 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 @@ -1094,69 +1091,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 - * 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 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 ); @@ -1166,40 +1163,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 { @@ -1211,8 +1208,8 @@ ( FALSE == props.alarmNoEndTreatment ) ) { endTxOnlyAlarmActive = TRUE; - } - } // If alarm active + } + } // If alarm active } // Alarm table loop // If top alarm condition not cleared, block resume @@ -1255,16 +1252,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; } /*********************************************************************//** @@ -1305,32 +1302,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 @@ -1415,23 +1412,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 ) { @@ -1470,7 +1467,7 @@ return result; } - + /*********************************************************************//** * @brief * The testClearAllAlarms function clears all active alarms, even if they @@ -1566,56 +1563,4 @@ return result; } -/*********************************************************************//** - * @brief - * The testGetAlarmPropertiesRequest function processes a request - * to retrieve alarm properties and broadcasts the result. - * @details \b Inputs: None - * @details \b Outputs: None - * @param message Pointer to MESSAGE_T containing the alarm ID request - * @return TRUE if alarm properties were successfully broadcasted. - * FALSE if payload length is invalid or alarm ID - * is out of range - *************************************************************************/ -BOOL testGetAlarmPropertiesRequest( MESSAGE_T *message ) -{ - ALARM_ID_T alarmID; - BOOL result = FALSE; - - if ( message->hdr.payloadLen == sizeof( U32 ) ) - { - memcpy( &alarmID, message->payload, sizeof( ALARM_ID_T ) ); - - if ( alarmID < NUM_OF_ALARM_IDS ) - { - ALARM_PROP_T canMsg; - ALARM_T alarm = getAlarmProperties( alarmID ); - - canMsg.alarmPriority = (U08)alarm.alarmPriority; - canMsg.alarmSubRank = (U16)alarm.alarmSubRank; - canMsg.alarmSource = (U08)alarm.alarmSource; - canMsg.alarmIsFault = (U08)alarm.alarmIsFault; - canMsg.alarmIsDDFault = (U08)alarm.alarmIsDDFault; - canMsg.alarmStops = (U08)alarm.alarmStops; - canMsg.alarmConditionClearImmed = (U08)alarm.alarmConditionClearImmed; - canMsg.alarmNoClear = (U08)alarm.alarmNoClear; - canMsg.alarmNoResume = (U08)alarm.alarmNoResume; - canMsg.alarmNoRinseback = (U08)alarm.alarmNoRinseback; - canMsg.alarmNoEndTreatment = (U08)alarm.alarmNoEndTreatment; - canMsg.alarmBlockRinseback = (U08)alarm.alarmBlockRinseback; - canMsg.alarmBlockEndTx = (U08)alarm.alarmBlockEndTx; - canMsg.alarmNoBloodRecirc = (U08)alarm.alarmNoBloodRecirc; - canMsg.alarmNoDialysateRecirc = (U08)alarm.alarmNoDialysateRecirc; - canMsg.alarmAutoResume = (U08)alarm.alarmAutoResume; - canMsg.alarmClearOnly = (U08)alarm.alarmClearOnly; - canMsg.alarmTreatmentLog = (U08)alarm.alarmTreatmentLog; - canMsg.alarmID = (U16)alarm.alarmID; - - result = broadcastData( MSG_ID_TD_ALARM_PROPERTIES_RESPONSE, COMM_BUFFER_OUT_CAN_PC, (U08*)&canMsg, sizeof( ALARM_PROP_T ) ); - } - } - - return result; -} - /**@}*/ Index: firmware/App/Services/AlarmMgmtTD.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/AlarmMgmtTD.h (.../AlarmMgmtTD.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/AlarmMgmtTD.h (.../AlarmMgmtTD.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file AlarmMgmtTD.h * -* @author (last) Santhosh Reddy -* @date (last) 06-Jul-2026 +* @author (last) Praneeth Bunne +* @date (last) 28-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -156,7 +156,6 @@ void handleResendActiveAlarmsRequest( void ); void handleAutoResumeAlarm( ALARM_ID_T alarm ); -BOOL testGetAlarmPropertiesRequest( MESSAGE_T *message ); BOOL testSetAlarmStartTimeOverride( MESSAGE_T *message ); BOOL testClearAllAlarms( MESSAGE_T *message ); BOOL testAlarmStatusPublishIntervalOverride( MESSAGE_T *message ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Santhosh Reddy -* @date (last) 06-Jul-2026 +* @author (last) Vijay Pamula +* @date (last) 08-Jun-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -132,7 +132,6 @@ { MSG_ID_UI_BLOOD_PRIME_CMD_REQUEST, &bloodPrimeHandleCmdRequest }, { MSG_ID_UI_TREATMENT_SET_POINT_BLOOD_FLOW_CHANGE_REQUEST, &bloodPrimeHandleBloodFlowChangeRequest }, { MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST, &handleAutoLoadRequest }, - { MSG_ID_TD_SETUP_TUBING_SET_CONNECTIONS_CONFIRM_REQUEST, &handleSetupTubingSetConnectionConfirmRequest }, { MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST, &handleAutoEjectRequest }, { MSG_ID_FFU_SIGNAL_TD_UPDATE_AVAILABLE, &handleUpdateAvailable }, { MSG_ID_UI_FLUID_BOLUS_REQUEST, &handleFluidBolusRequest }, @@ -218,7 +217,6 @@ { MSG_ID_TD_SYRINGE_PUMP_ADC_READ_COUNTER_OVERRIDE_REQUEST, &testSyringePumpADCReadCounterOverride }, { MSG_ID_TD_HEPARIN_BOLUS_TARGET_RATE_OVERRIDE_REQUEST, &testHeparinBolusTargetRateOverride }, { MSG_ID_TD_SYRINGE_PUMP_FORCE_SENSOR_CALIBRATION_REQUEST, &testCalibrateForceSensor }, - { MSG_ID_TD_GET_ALARM_PROPERTIES_REQUEST, &testGetAlarmPropertiesRequest }, }; /// Number of entries in the message handling function lookup table. Index: firmware/App/Services/StateServices/FluidBolus.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file FluidBolus.c * * @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @date (last) 04-Jun-2026 * * @author (original) Praneeth Bunne * @date (original) 04-Jun-2026 @@ -20,15 +20,13 @@ #include "DDInterface.h" #include "FluidBolus.h" #include "Messaging.h" -#include "ModeStandby.h" -#include "ModeTreatment.h" #include "Pressures.h" +#include "ModeTreatment.h" #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" #include "TaskGeneral.h" #include "Timers.h" -#include "TubeSetInstall.h" #include "TxParams.h" #include "Valves.h" @@ -39,32 +37,48 @@ // ********** 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. // ********** private data ********** static FLUID_BOLUS_STATE_T currentFluidBolusState; ///< Current fluid bolus state -static FLUID_TYPE_T fluidType; ///< Fluid type for bolus +static FLUID_BOLUS_MEDIUM_T currentFluidBolusMedium; ///< Current fluid bolus medium static U32 fluidBolusBroadCastTimerCtr; ///< Broadcast Timer counter 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 handleFluidBolusInProgressState( void ); +static FLUID_BOLUS_STATE_T handleFluidBolusSalineInProgressState( void ); +static FLUID_BOLUS_STATE_T handleFluidBolusSubstituteInProgressState( void ); /*********************************************************************//** * @brief @@ -75,14 +89,13 @@ * @details \b Outputs: currentFluidBolusState, currentFluidBolusMedium, * fluidBolusBroadCastTimerCtr, targetBloodFlowMLPM, totalFluidVolumeDelivered_mL, * bolusFluidVolumeDelivered_mL, fluidBolusStartRequested, - * fluidBolusAbortRequested, bolusVolumeLastUpdateTimeStamp, pubBolusPermitted, - * newAlarmIndicateStop + * fluidBolusAbortRequested, bolusVolumeLastUpdateTimeStamp, pubBolusPermitted * @return none *************************************************************************/ void initFluidBolus( void ) { currentFluidBolusState = FLUID_BOLUS_IDLE_STATE; - fluidType = getFluidType(); + currentFluidBolusMedium = getFluidBolusMedium(); fluidBolusBroadCastTimerCtr = FLUID_BOLUS_DATA_PUB_INTERVAL - 10; // setup to stagger publish from other broadcasters targetBloodFlowMLPM = 0; totalFluidVolumeDelivered_mL = 0.0F; @@ -91,24 +104,23 @@ fluidBolusAbortRequested = FALSE; bolusVolumeLastUpdateTimeStamp = getMSTimerCount(); pubBolusPermitted = TRUE; - newAlarmIndicateStop = FALSE; } /*********************************************************************//** * @brief * The execFluidBolus function executes the fluid bolus state machine. - * @details \b Inputs: currentFluidBolusState, newAlarmIndicateStop - * @details \b Outputs: currentFluidBolusState, newAlarmIndicateStop + * @details \b Inputs: currentFluidBolusState + * @details \b Outputs: currentFluidBolusState * @return none *************************************************************************/ void execFluidBolus( void ) { FLUID_BOLUS_STATE_T priorState = currentFluidBolusState; // If alarm fires while bolus is active, abort the bolus - if ( ( TRUE == newAlarmIndicateStop ) && ( TRUE == isFluidBolusActive() ) ) + if ( ( TRUE == doesAlarmStatusIndicateStop() ) && ( TRUE == isFluidBolusActive() ) && + ( TREATMENT_PAUSED_STATE != getTreatmentState() ) ) { - newAlarmIndicateStop = FALSE; signalAbortFluidBolus(); } @@ -122,10 +134,14 @@ currentFluidBolusState = handleFluidBolusWait4Pumps2Stop(); break; - case FLUID_BOLUS_IN_PROGRESS_STATE: - currentFluidBolusState = handleFluidBolusInProgressState(); + case FLUID_BOLUS_SALINE_IN_PROGRESS_STATE: + currentFluidBolusState = handleFluidBolusSalineInProgressState(); 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; @@ -156,6 +172,29 @@ /*********************************************************************//** * @brief + * The getFluidBolusMedium function determines the fluid bolus medium based + * on the current treatment modality and online fluid configuration. + * Substitution fluid applies to HDF treatment, or HD treatment with online + * fluid enabled. Saline applies to standard HD without online fluid. + * @details \b Inputs: none + * @details \b Outputs: none + * @return FLUID_BOLUS_MEDIUM_SUBSTITUTE for HDF or HD-online, FLUID_BOLUS_MEDIUM_SALINE otherwise. + *************************************************************************/ +FLUID_BOLUS_MEDIUM_T getFluidBolusMedium( void ) +{ + 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 ) + { + medium = FLUID_BOLUS_MEDIUM_SUBSTITUTE; + } + + return medium; +} + +/*********************************************************************//** + * @brief * The isFluidBolusActive function determines whether a fluid bolus is * currently being delivered. * @details \b Inputs: currentFluidBolusState @@ -259,8 +298,7 @@ * The handleFluidBolusIdleState function handles the idle state of the * fluid bolus state machine. * @details \b Inputs: fluidBolusStartRequested - * @details \b Outputs: fluidBolusStartRequested, bolusVolumeLastUpdateTimeStamp, - * newAlarmIndicateStop + * @details \b Outputs: fluidBolusStartRequested, bolusVolumeLastUpdateTimeStamp * @return next fluid bolus state *************************************************************************/ static FLUID_BOLUS_STATE_T handleFluidBolusIdleState( void ) @@ -271,8 +309,6 @@ 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 @@ -313,67 +349,93 @@ setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); - if ( FLUID_TYPE_SALINE == fluidType ) + if ( FLUID_BOLUS_MEDIUM_SALINE == currentFluidBolusMedium ) { setBloodPumpTargetFlowRate( targetBloodFlowMLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + state = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; } - else + else if ( TRUE == isDialysateGoodToDeliver ) { // set D92 flow rate cmdSubstitutionRate( (F32)targetBloodFlowMLPM ); + state = FLUID_BOLUS_SUBSITUTE_IN_PROGRESS_STATE; } - - state = FLUID_BOLUS_IN_PROGRESS_STATE; + else + { + state = FLUID_BOLUS_IDLE_STATE; + } } return state; } /*********************************************************************//** * @brief - * 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 Alarms: ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or - * saline line is clamped. - * @details \b Inputs: bolusFluidVolumeDelivered_mL, fluidBolusAbortRequested, - * currentFluidBolusMedium + * 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 * @details \b Outputs: fluidBolusAbortRequested * @return next fluid bolus state *************************************************************************/ -static FLUID_BOLUS_STATE_T handleFluidBolusInProgressState( void ) +static FLUID_BOLUS_STATE_T handleFluidBolusSalineInProgressState( void ) { - FLUID_BOLUS_STATE_T state = FLUID_BOLUS_IN_PROGRESS_STATE; - F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); + FLUID_BOLUS_STATE_T state = FLUID_BOLUS_SALINE_IN_PROGRESS_STATE; + F32 bolusTargetVolume = (F32)getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); updateFluidBolusVolumeDelivered(); - if ( FLUID_TYPE_SALINE == fluidType ) + // Check for empty saline bag per arterial line pressure + if ( TRUE == isSalineBagEmpty() ) { - // 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; - } + 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 { - if ( FALSE == getDialysateGoodToDeliverStatus() ) - { - state = FLUID_BOLUS_IDLE_STATE; - } + // No action required } - // Bolus ended or target volume reached or aborted, stop delivery and record volume. - if ( ( bolusFluidVolumeDelivered_mL >= bolusTargetVolume ) || ( TRUE == fluidBolusAbortRequested ) || - ( FLUID_BOLUS_IDLE_STATE == state ) ) + // Bolus ended, stop blood pump and record delivered volume + if ( state != FLUID_BOLUS_SALINE_IN_PROGRESS_STATE ) { - fluidBolusAbortRequested = FALSE; 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; cmdSubstitutionRate( 0.0F ); completeBolusToCumulative(); state = FLUID_BOLUS_IDLE_STATE; @@ -414,6 +476,58 @@ } /*********************************************************************//** + * @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 @@ -439,6 +553,18 @@ // 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 @@ -454,11 +580,6 @@ 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; @@ -511,17 +632,4 @@ 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 -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/FluidBolus.h (.../FluidBolus.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/FluidBolus.h (.../FluidBolus.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file FluidBolus.h * * @author (last) Praneeth Bunne -* @date (last) 26-Jun-2026 +* @date (last) 04-Jun-2026 * * @author (original) Praneeth Bunne * @date (original) 04-Jun-2026 @@ -52,22 +52,23 @@ } FLUID_BOLUS_DATA_PAYLOAD_T; #pragma pack(pop) -// ********** public function prototypes ********** +// ********** public definitions ********** void initFluidBolus( void ); void publishFluidBolusData( void ); void execFluidBolus( void ); void setBolusPermitted( BOOL permitted ); FLUID_BOLUS_STATE_T getCurrentFluidBolusState( void ); +FLUID_BOLUS_MEDIUM_T getFluidBolusMedium( void ); BOOL isFluidBolusActive( void ); void signalStartFluidBolus( U32 flowRate ); void signalAbortFluidBolus( void ); F32 getTotalFluidBolusVolumeDelivered( void ); BOOL handleFluidBolusRequest( MESSAGE_T *message ); -void signalNewStopAlarmActivated( void ); +BOOL isBolusAllowedByActiveAlarms( void ); /**@}*/ Index: firmware/App/Services/StateServices/TubeSetAutoEject.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/TubeSetAutoEject.c (.../TubeSetAutoEject.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/TubeSetAutoEject.c (.../TubeSetAutoEject.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file TubeSetAutoEject.c * * @author (last) Praneeth Bunne -* @date (last) 11-Jun-2026 +* @date (last) 04-Jun-2026 * * @author (original) Praneeth Bunne * @date (original) 01-May-2026 @@ -124,8 +124,8 @@ if ( previousAutoEjectState != currentAutoEjectState ) { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousAutoEjectState, currentAutoEjectState ); previousAutoEjectState = currentAutoEjectState; + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousAutoEjectState, currentAutoEjectState ); } } Index: firmware/App/Services/StateServices/TubeSetAutoEject.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/TubeSetAutoEject.h (.../TubeSetAutoEject.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/TubeSetAutoEject.h (.../TubeSetAutoEject.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file TubeSetAutoEject.h * * @author (last) Praneeth Bunne -* @date (last) 12-Jun-2026 +* @date (last) 12-May-2026 * * @author (original) Praneeth Bunne * @date (original) 01-May-2026 @@ -35,14 +35,14 @@ /// Enumeration of Tube Set Auto-Eject states. enum Tube_Set_Auto_Eject_States { - TUBE_SET_AUTO_EJECT_STATE_AWAIT_CONFIRMATION = 0, ///< Waiting for user confirmation to auto-eject - TUBE_SET_AUTO_EJECT_STATE_HOMING, ///< Homing blood pump - TUBE_SET_AUTO_EJECT_STATE_EXTENDING_EJECTOR, ///< Extending ejector state - TUBE_SET_AUTO_EJECT_STATE_EJECTING, ///< Ejecting tubeset state - TUBE_SET_AUTO_EJECT_STATE_RETRACTING_EJECTOR, ///< Retracting ejector state - TUBE_SET_AUTO_EJECT_STATE_BACK_OFF, ///< Auto-Eject Back-off state - TUBE_SET_AUTO_EJECT_STATE_COMPLETE, ///< Auto-Eject complete state - NUM_OF_TUBE_SET_AUTO_EJECT_SUB_STATES, ///< Num of auto-eject sub-states + TUBE_SET_AUTO_EJECT_STATE_AWAIT_CONFIRMATION = 0, // Waiting for user confirmation to auto-eject + TUBE_SET_AUTO_EJECT_STATE_HOMING, // Homing blood pump + TUBE_SET_AUTO_EJECT_STATE_EXTENDING_EJECTOR, // Extending ejector state + TUBE_SET_AUTO_EJECT_STATE_EJECTING, // Ejecting tubeset state + TUBE_SET_AUTO_EJECT_STATE_RETRACTING_EJECTOR, // Retracting ejector state + TUBE_SET_AUTO_EJECT_STATE_BACK_OFF, // Auto-Eject Back-off state + TUBE_SET_AUTO_EJECT_STATE_COMPLETE, // Auto-Eject complete state + NUM_OF_TUBE_SET_AUTO_EJECT_SUB_STATES, // Num of auto-eject sub-states }; /// Type for TD Tube Set Auto-Eject service enumeration typedef enum Tube_Set_Auto_Eject_States TUBE_SET_AUTO_EJECT_STATE_T; @@ -53,7 +53,7 @@ void execTubeSetAutoEject( void ); // Execute the service state machine (call from ModePostTreat and ModeTreatment) BOOL isTubeSetAutoEjectComplete( void ); // Returns True once auto-eject finished successfully -BOOL handleAutoEjectRequest( MESSAGE_T *message ); // Handle UI auto-eject confirmation request +BOOL handleAutoEjectRequest( MESSAGE_T *message ); // Handle UI auto-eject confirmation request /**@}*/ Index: firmware/App/Services/StateServices/TubeSetInstall.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file TubeSetInstall.c * * @author (last) Praneeth Bunne -* @date (last) 26-Jun-2026 +* @date (last) 04-Jun-2026 * * @author (original) Praneeth Bunne * @date (original) 01-May-2026 @@ -17,7 +17,6 @@ #include "AlarmMgmtTD.h" #include "BloodFlow.h" -#include "DDInterface.h" #include "Messaging.h" #include "OperationModes.h" #include "PeristalticPump.h" @@ -26,7 +25,6 @@ #include "TDDefs.h" #include "Timers.h" #include "TubeSetInstall.h" -#include "TxParams.h" /** * @addtogroup TubeSetInstall @@ -44,24 +42,20 @@ // ********** private data ********** static BOOL confirmTubesetPlaced; ///< Flag indicating user has confirmed tubeset is placed -static BOOL setupConnectionsConfirmed; ///< Flag indicating user has confirmed setup connections are complete. static U32 bloodPumpTimerCounter; ///< Blood Pump timer counter static BOOL bpLastHome; ///< Flag for blood pump last home (for rising-edge) static U32 bpLeftHomeTimerCounter; ///< Timer counter to measure how long BP has been away from home 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 -static TUBE_SET_INSTALL_STATE_T handleAwaitBPDoorCloseState( void ); ///< Handle Await Blood Pump Door Close sub-state. -static TUBE_SET_INSTALL_STATE_T handleAutoLoadState( void ); ///< Handle Auto-Load sub-state -static TUBE_SET_INSTALL_STATE_T handleAwaitSetupConnectionConfirmationState( void ); ///< Handle Await Setup Connection Confirmation sub-state -static TUBE_SET_INSTALL_STATE_T handleAutoLoadBackOffState( void ); ///< Handle Auto-Load Back-off sub-state -static TUBE_SET_INSTALL_STATE_T handleInstallCompleteState( void ); ///< Handle Install complete state +static TUBE_SET_INSTALL_STATE_T handleAwaitTubesetConfirmationState( void ); ///< Handle Await Tubset Install Confirmation sub-state +static TUBE_SET_INSTALL_STATE_T handleAwaitBPDoorCloseState( void ); ///< Handle Await Blood Pump Door Close sub-state. +static TUBE_SET_INSTALL_STATE_T handleAutoLoadState( void ); ///< Handle Auto-Load sub-state +static TUBE_SET_INSTALL_STATE_T handleAutoLoadBackOffState( void ); ///< Handle Auto-Load Back-off sub-state +static TUBE_SET_INSTALL_STATE_T handleInstallCompleteState( void ); ///< Handle Install complete state /*********************************************************************//** * @brief @@ -73,14 +67,12 @@ **************************************************************************/ void initTubeSetInstall( void ) { - previousInstallState = TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION; - currentInstallState = TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION; - confirmTubesetPlaced = FALSE; - setupConnectionsConfirmed = FALSE; - bloodPumpTimerCounter = 0; - bpLastHome = TRUE; - bpLeftHomeTimerCounter = 0; - currentTubeSetType = TUBE_SET_TYPE_UNKNOWN; + previousInstallState = TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION; + currentInstallState = TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION; + confirmTubesetPlaced = FALSE; + bloodPumpTimerCounter = 0; + bpLastHome = TRUE; + bpLeftHomeTimerCounter = 0; } /*********************************************************************//** @@ -112,10 +104,6 @@ currentInstallState = handleAutoLoadBackOffState(); break; - case TUBE_SET_INSTALL_STATE_AWAIT_SETUP_CONNECTION_CONFIRMATION: - currentInstallState = handleAwaitSetupConnectionConfirmationState(); - break; - case TUBE_SET_INSTALL_STATE_COMPLETE: currentInstallState = handleInstallCompleteState(); break; @@ -127,8 +115,8 @@ if ( previousInstallState != currentInstallState ) { - SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousInstallState, currentInstallState ); previousInstallState = currentInstallState; + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, previousInstallState, currentInstallState ); } } @@ -144,24 +132,11 @@ static TUBE_SET_INSTALL_STATE_T handleAwaitTubesetConfirmationState( void ) { TUBE_SET_INSTALL_STATE_T state = TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION; - F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; if ( TRUE == confirmTubesetPlaced ) { // Door closed required from Auto-loading onwards, set to false if not required in subsequent states doorClosedRequired( TRUE ); - - // Request DD to generate dialysate with Qd = 600 mL/min, - // Quf = 0, and dialyzer bypassed. - cmdStartGenerateDialysate( 600.0F, - 0.0F, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), - TRUE, - getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), - bicarbConvFactor, - getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), - getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); - confirmTubesetPlaced = FALSE; state = TUBE_SET_INSTALL_STATE_AWAIT_BP_DOOR_CLOSE; } @@ -229,7 +204,7 @@ signalBloodPumpHardStop(); bloodPumpTimerCounter = 0; bpLeftHomeTimerCounter = 0; - state = TUBE_SET_INSTALL_STATE_AWAIT_SETUP_CONNECTION_CONFIRMATION; + state = TUBE_SET_INSTALL_STATE_COMPLETE; } else { @@ -248,28 +223,6 @@ /*********************************************************************//** * @brief - * The handleAwaitSetupConnectionConfirmationState function handles the - * Await Setup Connection Confirmation state of Tube Set install state. - * @details \b Inputs: setupConnectionsConfirmed - * @details \b Outputs: setupConnectionsConfirmed - * @return next Install sub-state - *************************************************************************/ -static TUBE_SET_INSTALL_STATE_T handleAwaitSetupConnectionConfirmationState( void ) -{ - TUBE_SET_INSTALL_STATE_T state = TUBE_SET_INSTALL_STATE_AWAIT_SETUP_CONNECTION_CONFIRMATION; - - if ( TRUE == setupConnectionsConfirmed ) - { - setupConnectionsConfirmed = FALSE; - - state = TUBE_SET_INSTALL_STATE_COMPLETE; - } - - return state; -} - -/*********************************************************************//** - * @brief * The handleAutoLoadBackOffState function handles the Auto-Load Back-Off * state of Tube Set install state. * @details \b Inputs: bloodPumpTimerCounter @@ -379,113 +332,4 @@ return result; } -/*********************************************************************//** - * @brief - * The handleSetupTubingSetConnectionConfirmRequest function handles a UI request - * to confirm setup connections are complete. - * @details \b Message \b Sent: MSG_ID_TD_SETUP_TUBING_SET_CONNECTIONS_CONFIRM_RESPONSE - * @details \b Inputs: none - * @details \b Outputs: setupConnectionsConfirmed - * @param message UI message which includes the user confirmation of - * setup connections completion. - * @return TRUE if confirmation accepted, FALSE otherwise. - *************************************************************************/ -BOOL handleSetupTubingSetConnectionConfirmRequest( MESSAGE_T *message ) -{ - BOOL result = FALSE; - UI_RESPONSE_PAYLOAD_T response; - - response.rejectionReason = REQUEST_REJECT_REASON_NONE; - - if ( 0 == message->hdr.payloadLen ) - { - if ( TUBE_SET_INSTALL_STATE_COMPLETE != currentInstallState ) - { - setupConnectionsConfirmed = TRUE; - result = TRUE; - } - else - { - response.rejectionReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; - } - } - else - { - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; - } - - response.accepted = result; - - sendMessage( MSG_ID_TD_SETUP_TUBING_SET_CONNECTIONS_CONFIRM_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); - - return result; -} - -/*********************************************************************//** -* The setTubeSetType function sets the current installed tube set type. - * @details \b Alarms: ALARM_ID_TD_SOFTWARE_FAULT if tube set is invalid 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 ) -{ - if ( type < NUM_OF_TUBE_SET_TYPES ) - { - currentTubeSetType = type; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TUBE_SET_TYPE, (U32)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; -} - -/*********************************************************************//** - * @brief - * The validateTubeSetType function validates the current installed tube set type - * based on modality. - * @details \b Alarm: - * @details \b Inputs: none - * @details \b Outputs: none - * @return none. - *************************************************************************/ -void validateTubeSetType( void ) -{ - U32 modality = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_MODALITY ); - BOOL misMatch = FALSE; - - if ( TREATMENT_MODALITY_HDF_ONLINE_FLUID == modality ) - { - if ( TUBE_SET_TYPE_HDF != currentTubeSetType ) - { - misMatch = TRUE; - } - } - else - { - if ( TREATMENT_MODALITY_HD_SALINE_FLUID != currentTubeSetType ) - { - misMatch = TRUE; - } - } - - if ( TRUE == misMatch ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_TUBE_SET_MISMATCH, modality, (U32)currentTubeSetType ); - } -} - /**@}*/ Index: firmware/App/Services/StateServices/TubeSetInstall.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/StateServices/TubeSetInstall.h (.../TubeSetInstall.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/StateServices/TubeSetInstall.h (.../TubeSetInstall.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -8,7 +8,7 @@ * @file TubeSetInstall.h * * @author (last) Praneeth Bunne -* @date (last) 26-Jun-2026 +* @date (last) 04-May-2026 * * @author (original) Praneeth Bunne * @date (original) 01-May-2026 @@ -32,13 +32,12 @@ // ********** 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. TUBE_SET_INSTALL_STATE_AWAIT_BP_DOOR_CLOSE, // Waiting for blood pump door to be closed. TUBE_SET_INSTALL_STATE_AUTO_LOAD, // Auto-Load the tubeset state - TUBE_SET_INSTALL_STATE_AWAIT_SETUP_CONNECTION_CONFIRMATION, // Awaiting user confirmation that setup connections are complete. TUBE_SET_INSTALL_STATE_AUTO_LOAD_BACK_OFF, // Auto-Load Back-off state TUBE_SET_INSTALL_STATE_COMPLETE, // Install state complete NUM_OF_TUBE_SET_INSTALL_SUB_STATES, // Num of install sub-states @@ -48,17 +47,12 @@ // ********** public function prototypes ********** -void initTubeSetInstall( void ); // Initialize this service -void execTubeSetInstall( void ); // Execute the service state machine (call from ModePreTreat and ModeTreatment) +void initTubeSetInstall( void ); // Initialize this service +void execTubeSetInstall( void ); // Execute the service state machine (call from ModePreTreat and ModeTreatment) -BOOL isTubeSetInstallComplete( void ); // Returns True once auto-load finished successfully -BOOL handleAutoLoadRequest( MESSAGE_T *message ); // Handle UI auto-load confirmation request -BOOL handleSetupTubingSetConnectionConfirmRequest( MESSAGE_T *message ); // Handle UI setup tubing set connection confirmation request +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 TODO: Call this after implementing bar code logic -TUBE_SET_TYPE_T getTubeSetType( void ); // Get the current installed tube set type -void validateTubeSetType( void ); // Validate tube set type with the modality TODO: call this after implementing bar code logic and setting the tube set type - /**@}*/ #endif Index: firmware/App/Services/SystemCommTD.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/SystemCommTD.c (.../SystemCommTD.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/SystemCommTD.c (.../SystemCommTD.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,42 +7,42 @@ * * @file SystemCommTD.c * -* @author (last) Praneeth Bunne -* @date (last) 12-Jun-2026 +* @author (last) Dara Navaei +* @date (last) 06-Mar-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 * ***************************************************************************/ - -#include // For memcpy() - -#include "can.h" -#include "sci.h" -#include "sys_dma.h" - -#include "Comm.h" + +#include // For memcpy() + +#include "can.h" +#include "sci.h" +#include "sys_dma.h" + +#include "Comm.h" #include "Interrupts.h" -#include "Messaging.h" +#include "Messaging.h" #include "OperationModes.h" #include "SystemCommTD.h" -#include "Timers.h" -#include "Utilities.h" - +#include "Timers.h" +#include "Utilities.h" + /** * @addtogroup SystemCommTD * @{ */ -// ********** private definitions ********** - +// ********** private definitions ********** + #define UI_COMM_TIMEOUT_IN_MS 7500 ///< Maximum time (in ms) that UI is allowed to wait before checking in with HD. -#define UI_COMM_SERVICE_MODE_TIMEOUT_IN_MS (2 * SEC_PER_MIN * MS_PER_SECOND) ///< Maximum time (in ms) that UI is allowed to wait before checking in with HD when in service mode. -#define DG_COMM_TIMEOUT_IN_MS 1000 ///< DG has not checked in for this much time - -#define MAX_COMM_CRC_FAILURES 5 ///< Maximum number of CRC errors within window period before alarm -#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window - +#define UI_COMM_SERVICE_MODE_TIMEOUT_IN_MS (2 * SEC_PER_MIN * MS_PER_SECOND) ///< Maximum time (in ms) that UI is allowed to wait before checking in with HD when in service mode. +#define DG_COMM_TIMEOUT_IN_MS 1000 ///< DG has not checked in for this much time + +#define MAX_COMM_CRC_FAILURES 5 ///< Maximum number of CRC errors within window period before alarm +#define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window + #define MAX_FPGA_CLOCK_SPEED_ERRORS 3 ///< maximum number of FPGA clock speed errors within window period before alarm #define MAX_FPGA_CLOCK_SPEED_ERROR_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< FPGA clock speed error window @@ -70,122 +70,122 @@ COMM_BUFFER_IN_CAN_PC, }; -// ********** private data ********** - +// ********** private data ********** + static volatile BOOL tdIsOnlyCANNode = TRUE; ///< Flag indicating whether HD is alone on CAN bus. -static volatile BOOL ddIsCommunicating = FALSE; ///< Has DD sent a message since last check -static U32 timeOfLastDDCheckIn = 0; ///< Last time DD checked in -static volatile BOOL uiIsCommunicating = FALSE; ///< Has UI sent a message since last check -static U32 timeOfLastUICheckIn = 0; ///< Last time UI checked in +static volatile BOOL ddIsCommunicating = FALSE; ///< Has DD sent a message since last check +static U32 timeOfLastDDCheckIn = 0; ///< Last time DD checked in +static volatile BOOL uiIsCommunicating = FALSE; ///< Has UI sent a message since last check +static U32 timeOfLastUICheckIn = 0; ///< Last time UI checked in static volatile BOOL uiDidCommunicate = FALSE; ///< Has UI every sent a message - -// ********** private function prototypes ********** - - -/*********************************************************************//** - * @brief + +// ********** private function prototypes ********** + + +/*********************************************************************//** + * @brief * The initSystemCommTD function initializes the system communication unit - * for the TD firmware. - * @details \b Inputs: none - * @details \b Outputs: SystemComm unit initialized. - * @return none - *************************************************************************/ -void initSystemCommTD( void ) + * for the TD firmware. + * @details \b Inputs: none + * @details \b Outputs: SystemComm unit initialized. + * @return none + *************************************************************************/ +void initSystemCommTD( void ) { // Initialize common system comm unit initSystemComm(); - + // Initialize bad message CRC time windowed count initTimeWindowedCount( TIME_WINDOWED_COUNT_BAD_MSG_CRC, MAX_COMM_CRC_FAILURES, MAX_COMM_CRC_FAILURE_WINDOW_MS ); // Initialize FPGA clock speed error time windowed count initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CLOCK_SPEED_ERROR, MAX_FPGA_CLOCK_SPEED_ERRORS, MAX_FPGA_CLOCK_SPEED_ERROR_WINDOW_MS); -} - -/*********************************************************************//** - * @brief - * The checkInFromDD function checks in the DD with the TD - indicating that - * the DD is communicating. - * @details \b Inputs: none - * @details \b Outputs: ddIsCommunicating, timeOfLastDDCheckIn - * @return none - *************************************************************************/ -void checkInFromDD( void ) -{ - ddIsCommunicating = TRUE; +} + +/*********************************************************************//** + * @brief + * The checkInFromDD function checks in the DD with the TD - indicating that + * the DD is communicating. + * @details \b Inputs: none + * @details \b Outputs: ddIsCommunicating, timeOfLastDDCheckIn + * @return none + *************************************************************************/ +void checkInFromDD( void ) +{ + ddIsCommunicating = TRUE; timeOfLastDDCheckIn = getMSTimerCount(); if ( TRUE == isAlarmActive( ALARM_ID_TD_DD_COMM_TIMEOUT ) ) { clearAlarmCondition( ALARM_ID_TD_DD_COMM_TIMEOUT ); - } -} - -/*********************************************************************//** - * @brief - * The checkInFromUI function checks in the UI with the TD - indicating that - * the UI is communicating. - * @details \b Inputs: none - * @details \b Outputs: uiIsCommunicating, timeOfLastUICheckIn, uiDidCommunicate - * @return none - *************************************************************************/ -void checkInFromUI( void ) -{ + } +} + +/*********************************************************************//** + * @brief + * The checkInFromUI function checks in the UI with the TD - indicating that + * the UI is communicating. + * @details \b Inputs: none + * @details \b Outputs: uiIsCommunicating, timeOfLastUICheckIn, uiDidCommunicate + * @return none + *************************************************************************/ +void checkInFromUI( void ) +{ if ( FALSE == uiDidCommunicate ) { // Start DD check-in timer when UI first communicates timeOfLastDDCheckIn = getMSTimerCount(); } - - uiIsCommunicating = TRUE; - timeOfLastUICheckIn = getMSTimerCount(); - uiDidCommunicate = TRUE; -} - -/*********************************************************************//** - * @brief - * The isDDCommunicating function determines whether the DD is communicating - * with the TD. - * @details \b Inputs: ddIsCommunicating - * @details \b Outputs: none - * @return TRUE if DD is communicating, FALSE if not - *************************************************************************/ -BOOL isDDCommunicating( void ) -{ - return ddIsCommunicating; -} - -/*********************************************************************//** - * @brief - * The isUICommunicating function determines whether the UI is communicating - * with the TD. - * @details \b Inputs: uiIsCommunicating - * @details \b Outputs: uiIsCommunicating - * @return TRUE if UI has checked in since last call, FALSE if not - *************************************************************************/ -BOOL isUICommunicating( void ) -{ - BOOL result = uiIsCommunicating; - - uiIsCommunicating = FALSE; - - return result; -} - -/*********************************************************************//** - * @brief + + uiIsCommunicating = TRUE; + timeOfLastUICheckIn = getMSTimerCount(); + uiDidCommunicate = TRUE; +} + +/*********************************************************************//** + * @brief + * The isDDCommunicating function determines whether the DD is communicating + * with the TD. + * @details \b Inputs: ddIsCommunicating + * @details \b Outputs: none + * @return TRUE if DD is communicating, FALSE if not + *************************************************************************/ +BOOL isDDCommunicating( void ) +{ + return ddIsCommunicating; +} + +/*********************************************************************//** + * @brief + * The isUICommunicating function determines whether the UI is communicating + * with the TD. + * @details \b Inputs: uiIsCommunicating + * @details \b Outputs: uiIsCommunicating + * @return TRUE if UI has checked in since last call, FALSE if not + *************************************************************************/ +BOOL isUICommunicating( void ) +{ + BOOL result = uiIsCommunicating; + + uiIsCommunicating = FALSE; + + return result; +} + +/*********************************************************************//** + * @brief * The uiCommunicated function determines whether the UI has started communicating - * since power up. - * @details \b Inputs: uiDidCommunicate - * @details \b Outputs: none - * @return TRUE if UI has communicated since power up, FALSE if not - *************************************************************************/ -BOOL uiCommunicated( void ) + * since power up. + * @details \b Inputs: uiDidCommunicate + * @details \b Outputs: none + * @return TRUE if UI has communicated since power up, FALSE if not + *************************************************************************/ +BOOL uiCommunicated( void ) { #ifdef TEST_PROCESS_TASKS_WO_UI uiDidCommunicate = TRUE; #endif - return uiDidCommunicate; + return uiDidCommunicate; } /*********************************************************************//** @@ -213,8 +213,8 @@ void setOnlyCANNode( BOOL only ) { tdIsOnlyCANNode = only; -} - +} + /*********************************************************************//** * @brief * The clearCANXmitBuffers function clears all CAN transmit buffers. @@ -232,34 +232,34 @@ } } -/*********************************************************************//** - * @brief - * The checkForCommTimeouts function checks for sub-system communication +/*********************************************************************//** + * @brief + * The checkForCommTimeouts function checks for sub-system communication * timeout errors. * @details \b Alarm: ALARM_ID_TD_UI_COMM_TIMEOUT if UI no longer communicating. - * @details \b Alarm: ALARM_ID_TD_DD_COMM_TIMEOUT if DD no longer communicating. - * @details \b Inputs: timeOfLastDDCheckIn, timeOfLastUICheckIn - * @details \b Outputs: none - * @return none - *************************************************************************/ -void checkForCommTimeouts( void ) -{ - if ( TRUE == uiDidCommunicate ) + * @details \b Alarm: ALARM_ID_TD_DD_COMM_TIMEOUT if DD no longer communicating. + * @details \b Inputs: timeOfLastDDCheckIn, timeOfLastUICheckIn + * @details \b Outputs: none + * @return none + *************************************************************************/ +void checkForCommTimeouts( void ) +{ + if ( TRUE == uiDidCommunicate ) { TD_OP_MODE_T opMode = getCurrentOperationMode(); U32 uiTO_MS = ( MODE_SERV == opMode ? UI_COMM_SERVICE_MODE_TIMEOUT_IN_MS : UI_COMM_TIMEOUT_IN_MS ); - if ( TRUE == didTimeout( timeOfLastUICheckIn, uiTO_MS ) ) + if ( TRUE == didTimeout( timeOfLastUICheckIn, uiTO_MS ) ) { #ifndef _RELEASE_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_UI_COMM_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif - { + { #ifndef TEST_DISABLE_UI_ALARMS activateAlarmNoData( ALARM_ID_TD_UI_COMM_TIMEOUT ); #endif } - } + } if ( TRUE == didTimeout( timeOfLastDDCheckIn, DG_COMM_TIMEOUT_IN_MS ) ) { @@ -353,21 +353,21 @@ return result; -} - -/*********************************************************************//** - * @brief - * The processReceivedMessage function processes a given message. - * @details \b Inputs: none - * @details \b Outputs: message processed - * @param message Pointer to the message to process. - * @return none - *************************************************************************/ -void processReceivedMessage( MESSAGE_T *message ) -{ +} + +/*********************************************************************//** + * @brief + * The processReceivedMessage function processes a given message. + * @details \b Inputs: none + * @details \b Outputs: message processed + * @param message Pointer to the message to process. + * @return none + *************************************************************************/ +void processReceivedMessage( MESSAGE_T *message ) +{ // Handle any messages from other sub-systems - handleIncomingMessage( message ); -} + handleIncomingMessage( message ); +} /************************************************************************* Index: firmware/App/Services/TxParams.c =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/Services/TxParams.c (.../TxParams.c) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/Services/TxParams.c (.../TxParams.c) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file TxParams.c * -* @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @author (last) Vijay Pamula +* @date (last) 11-Jun-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 02-Dec-2025 @@ -21,7 +21,6 @@ #include "BloodFlow.h" #include "Buttons.h" #include "Messaging.h" -#include "ModeStandby.h" #include "ModeTreatment.h" #include "ModePreTreat.h" #include "OperationModes.h" @@ -576,11 +575,11 @@ switch ( txType ) { - case TREATMENT_MODALITY_HDF_ONLINE_FLUID: + case TREATMENT_MODALITY_HDF: result = FALSE; break; - case TREATMENT_MODALITY_HD_SALINE_FLUID: + case TREATMENT_MODALITY_HD: result = ( ( ( param == TREATMENT_PARAM_HDF_DILUTION ) || ( param == TREATMENT_PARAM_SUBST_FLUID_VOLUME ) ) ? TRUE : FALSE ); break; @@ -739,7 +738,6 @@ F32 hepDR = stagedParams[ TREATMENT_PARAM_HEPARIN_DELIVERY_RATE ].sFlt; F32 hepBV = stagedParams[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].sFlt; F32 txVol = hepBV + ( hepDR * ( hepST / (F32)SEC_PER_MIN ) ) + SYRINGE_PUMP_PRIME_VOLUME_ML + SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML; - TREATMENT_TYPE_T modality = (TREATMENT_TYPE_T)stagedParams[ TREATMENT_PARAM_TREATMENT_MODALITY ].uInt; // Variable to validate acid conversion factor consistency U32 acidType = stagedParams[ TREATMENT_PARAM_ACID_CONCENTRATE ].uInt; @@ -770,13 +768,6 @@ result = FALSE; } - // Verify Rx entered modality with the treatment initiation modality - if ( modality != getModality() ) - { - reasons[ TREATMENT_PARAM_TREATMENT_MODALITY ] = REQUEST_REJECT_REASON_MODALITY_MISMATCH; - result = FALSE; - } - return result; } Index: firmware/App/TDCommon.h =================================================================== diff -u -r069dee3a2428d3c6bb281db1844a372ae6e2063a -re4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67 --- firmware/App/TDCommon.h (.../TDCommon.h) (revision 069dee3a2428d3c6bb281db1844a372ae6e2063a) +++ firmware/App/TDCommon.h (.../TDCommon.h) (revision e4eceb1ac6e8091d10e0fab49d2d5a9c5e5f1c67) @@ -7,8 +7,8 @@ * * @file TDCommon.h * -* @author (last) Varshini Nagabooshanam -* @date (last) 02-Jul-2026 +* @author (last) Dara Navaei +* @date (last) 27-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -25,7 +25,7 @@ #define TD_VERSION_MAJOR 0 #define TD_VERSION_MINOR 0 #define TD_VERSION_MICRO 0 -#define TD_VERSION_BUILD 58 +#define TD_VERSION_BUILD 55 // ********** development build switches **********