Index: firmware/App/Modes/ModeTreatment.c
===================================================================
diff -u -r95c81a7d81fa3e6534bcf2e35e1d9b1eba26e372 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 95c81a7d81fa3e6534bcf2e35e1d9b1eba26e372)
+++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -29,6 +29,7 @@
#include "OperationModes.h"
#include "Pressures.h"
#include "StateTxBloodPrime.h"
+#include "TreatmentEnd.h"
#include "StateTxDialysis.h"
#include "StateTxPaused.h"
#include "StateTxRecirc.h"
@@ -105,6 +106,8 @@
static U32 treatmentStartTimeStamp; ///< Treatment start timestamp for logging purpose.
static U32 treatmentEndTimeStamp; ///< Treatment end timestamp for logging purpose.
+static BOOL treatmentEndToRinsebackRequest; ///< Flag indicates treatment end sub-mode has requested transition to Rinseback.
+
// ********** private function prototypes **********
static void broadcastTreatmentSettingsRanges( void );
@@ -193,15 +196,10 @@
initBloodPrime();
initDialysis();
initTreatmentPaused();
-<<<<<<< HEAD
-// initRinseback();
-// initTreatmentRecirc();
- initTreatmentEnd();
-=======
+
initRinseback();
initTreatmentRecirc();
-// initTreatmentEnd();
->>>>>>> staging
+ initTreatmentEnd();
initFluidBolus();
// Started the treatment - set the start time in epoch
@@ -525,7 +523,7 @@
resumeBlockedByAlarm = TRUE;
}
- // Check dialysate temperature during treatment mode (except end state where treatment is over, dialyzer is bypassed and temp is no longer an issue)
+// Check dialysate temperature during treatment mode (except end state where treatment is over, dialyzer is bypassed and temp is no longer an issue)
// if ( currentTreatmentState != TREATMENT_END_STATE )
// {
// checkDialysateTemperature();
@@ -756,10 +754,16 @@
treatmentCompleted = TRUE;
// sendLastTreatmentPeriodicData = TRUE;
// treatmentEndTimeStamp = getRTCTimestamp();
- pauseDialysis();
- //requestNewOperationMode( MODE_STAN ); // TODO
+// pauseDialysis();
+
+ /// CKOE
+ // stopDialysis();
transitionToTreatmentEnd();
+
+ //CKOE Do we need data to broadd cast here
//SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TD_END_OF_TREATMENT_WARNING, presTreatmentTimeSecs );
+ // Trigger the low-priority End of Treatment alarm
+ activateAlarmNoData( ALARM_ID_TD_END_OF_TREATMENT );
result = TREATMENT_END_STATE;
}
// Otherwise, execute state machine for treatment dialysis sub-mode
@@ -932,39 +936,34 @@
* @details \b Outputs: treatment end sub-mode executed.
* @return next treatment mode state
*************************************************************************/
+
+
static TREATMENT_STATE_T handleTreatmentEndState( void )
{
TREATMENT_STATE_T result = TREATMENT_END_STATE;
- // Handle final rinseback alarm response from user
-// if ( TRUE == initiateRinsebackAlarmResponseRequest )
-// {
-// signalTreatmentEndAlarmRinsebackUserAction();
-// }
-// // Handle alarm response from user to end treatment w/o rinseback
-// else if ( TRUE == endTreatmentAlarmResponseRequest )
-// {
-// signalTreatmentEndAlarmEndTxUserAction();
-// }
-// // End treatment state does not allow resume
-//
-// // Execute treatment end sub-mode
-// execTreatmentEnd();
-//
-// // Handle signals from treatment end sub-mode
-// if ( TRUE == treatmentEndToRinsebackRequest )
-// {
-// transitionToRinseback();
-// result = TREATMENT_RINSEBACK_STATE;
-// }
-// else if ( TRUE == endTreatmentRequest )
-// {
-// requestNewOperationMode( MODE_POST );
-// }
+// // Handle final rinseback alarm response from user
+ if ( TRUE == initiateRinsebackAlarmResponseRequest )
+ {
+ signalTreatmentEndAlarmRinsebackUserAction();
+ }
+ // Handle alarm response from user to end treatment w/o rinseback
+ else if ( TRUE == endTreatmentAlarmResponseRequest )
+ {
+ //sendLastTreatmentPeriodicData = TRUE; TODO
+ requestNewOperationMode( MODE_POST );
+ }
+ // End treatment state does not allow resume
+ // Execute treatment end sub-mode
+ execTreatmentEnd();
+ if ( TRUE == treatmentEndToRinsebackRequest )
+ {
+ transitionToRinseback();
+ result = TREATMENT_RINSEBACK_STATE;
+ }
return result;
}
-
/*********************************************************************//**
* @brief
* The broadcastTreatmentTimeAndState function broadcasts treatment time and
@@ -1027,7 +1026,7 @@
payload.txPausedState = getCurrentTreatmentPausedState();
payload.rinsebackState = getCurrentRinsebackState();
payload.txRecircState = getCurrentTreatmentRecircState();
- payload.txEndState = 0; // getCurrentTreatmentEndState();
+ payload.txEndState = getCurrentTreatmentEndState();
payload.txFluidBolusState = getCurrentFluidBolusState();
payload.txHepState = 0; //
broadcastData( MSG_ID_TD_TREATMENT_STATE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&payload), sizeof( TREATMENT_STATE_DATA_T ) );
@@ -1213,7 +1212,7 @@
endTreatmentRequest = FALSE;
rinsebackToRecircRequest = FALSE;
bloodPrimeToDialysisRequest = FALSE;
-// treatmentEndToRinsebackRequest = FALSE; // TODO: Declare & uncomment when end treat is implemented.
+ treatmentEndToRinsebackRequest = FALSE;
recirculateToBloodPrimeRequest = FALSE;
}
@@ -1234,6 +1233,18 @@
/*********************************************************************//**
* @brief
+ * The signalTreatmentEndToRinseback function signals that treatment end
+ * sub-mode wants to transition to the rinseback sub-mode.
+ * @details Inputs: none
+ * @details Outputs: treatmentEndToRinsebackRequest
+ * @return none
+ *************************************************************************/
+void signalTreatmentEndToRinseback( void )
+{
+ treatmentEndToRinsebackRequest = TRUE;
+}
+/*********************************************************************//**
+ * @brief
* The publishUltrafiltrationData function publishes the ultrafiltration data
* at the set time interval.
* @details \b Inputs: none
Index: firmware/App/Modes/ModeTreatment.h
===================================================================
diff -u -ra1f14a4e422f94b6bc25d1b91839761e7e1196d7 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision a1f14a4e422f94b6bc25d1b91839761e7e1196d7)
+++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -133,7 +133,9 @@
// MSG_ID_TD_PRESSURE_LIMITS_CHANGE_RESPONSE
BOOL sendPressureLimitsChangeResponse( PRESSURE_LIMIT_CHANGE_RESPONSE_T *data );
+void signalTreatmentEndToRinseback( void );
+
/**@}*/
#endif
Index: firmware/App/Modes/StateTxDialysis.c
===================================================================
diff -u -r95c81a7d81fa3e6534bcf2e35e1d9b1eba26e372 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 95c81a7d81fa3e6534bcf2e35e1d9b1eba26e372)
+++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -248,7 +248,7 @@
// Make rate changes in real time if currently performing dialysis.
if ( (TREATMENT_END_STATE == getTreatmentState() ))
{
- setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP );
+ setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP );
}
}
@@ -385,6 +385,25 @@
/*********************************************************************//**
* @brief
+ * The stopDialysis function stops dialysis. This function will be called
+ * by Treatment Mode when an alarm occurs or the user pressed the stop button.
+ * Dialysis may be resumed later.
+ * @details Inputs: none
+ * @details Outputs: Blood and dialysate pumps stopped. Heparin pump stopped.
+ * @return none
+ *************************************************************************/
+void stopDialysis( void )
+{
+ // Stop pumps
+ signalBloodPumpHardStop();
+ stopSyringePump();
+
+ // CKOE whta command used for trimmer heater to stop
+ // Tell DG to stop heating dialysate
+ //cmdStopDGTrimmerHeater();
+}
+/*********************************************************************//**
+ * @brief
* The execDialysis function executes the Dialysis sub-mode state machine.
* @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if state is invalid
* @details \b Message \b Sent: TD_EVENT_SUB_STATE_CHANGE when state changes
Index: firmware/App/Modes/TreatmentEnd.c
===================================================================
diff -u -r9d80274d4f31715890d519f5f9fbe445c4614046 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 9d80274d4f31715890d519f5f9fbe445c4614046)
+++ firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -5,7 +5,7 @@
* Author: fw
*/
#include "DDInterface.h"
-
+#include "string.h"
#include "AirTrap.h"
#include "BloodFlow.h"
#include "ModeTreatment.h"
@@ -22,200 +22,184 @@
#include "Bubbles.h"
#include "Switches.h"
#include "Common.h"
+#include "Messaging.h"
+#include "TDDefs.h"
+#include "StateTxPaused.h"
/**
* @addtogroup TreatmentEnd
* @{
*/
// ********** private definitions ***********
-/// Placeholder End of Treatment blood pump flow rate (mL/min).
-// TODO CONFIRM #6: reuse TREATMENT_PARAM_BLOOD_FLOW via getTreatmentParameterU32(), or a
-// dedicated End-of-Treatment rate param — not yet located in this codebase. Using a local
-// placeholder constant here in the meantime so the file compiles.
-#define TX_END_BP_FLOW_RATE_ML_MIN 150
-
-/// Interval at which treatment end progress is to be published to UI.
-#define TREATMENT_END_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL )
-
/// Time before escalating the low-priority End of Treatment alarm to high priority.
static const U32 TX_END_ESCALATION_TIMEOUT_MS = ( ( 10 * 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL );
-typedef enum ENDTREATMENT_STATES_T
-{
- TX_END_WAIT_FOR_RINSEBACK_STATE,
- TX_END_FLUID_BOLUS_STATE,
- TX_END_PAUSED_STATE,
- NO_OF_TX_END_STATES
-} ENDTREATMENT_STATES_T;
-
// ********** private data **********
-static ENDTREATMENT_STATES_T treatmentEndState; ///< Current substate of Treatment End.
+static TREATMENT_END_STATE_T treatmentEndState; ///< Current substate of Treatment End.
+static U32 txEndTimerCtr; ///< Timer counter (GP task intervals) tracking time in Wait for Rinseback, drives low->high alarm escalation.
+static U32 bloodSittingTimerCtr; ///< blood sitting timer counter
+static BOOL txEndAlarmRinsebackRequested; ///< User requested rinseback via alarm action / UI message.
+static BOOL txEndBolusRequested; ///< User requested a fluid bolus while in End of Treatment.
+static BOOL txEndEscalated; ///< Tracks whether the high-priority alarm has already been raised, to avoid re-triggering every cycle.
+static TREATMENT_END_STATE_T txEndPriorStateBeforeBolus;
-static U32 txEndTimerCtr; ///< Timer counter (GP task intervals) tracking time in Wait for Rinseback, drives low->high alarm escalation.
-static U32 treatmentEndPublishTimerCtr; ///< Timer counter for UI publish interval.
-
-static BOOL txEndAlarmRinsebackRequested; ///< User requested rinseback via alarm action / UI message.
-static BOOL txEndAlarmEndTreatmentOnlyRequested; ///< User requested "End Treatment Only" via alarm action / UI message.
-static BOOL txEndBolusRequested; ///< User requested a fluid bolus while in End of Treatment.
-static BOOL txEndEscalated; ///< Tracks whether the high-priority alarm has already been raised, to avoid re-triggering every cycle.
-static ENDTREATMENT_STATES_T txEndPriorStateBeforeBolus;
-
// ********** private function prototypes **********
-static void setupForTxEndWait4RinsebackState( void );
-static void setupForTxEndPausedState( void );
+static TREATMENT_END_STATE_T handleTxEndWaitForRinsebackState( void );
+static TREATMENT_END_STATE_T handleTxEndFluidBolusState( void );
+static TREATMENT_END_STATE_T handleTxEndPausedState( void );
static void resetTreatmentEndFlags( void );
-static void publishTreatmentEndData( void );
+static void setupForTreatmentEndSubState( TREATMENT_END_STATE_T newState );
+static void handleTreatmentEndBloodSittingTimer( void );
+static BOOL handleTxEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason );
-static ENDTREATMENT_STATES_T handleTxEndWait4RinsebackState( void );
-static ENDTREATMENT_STATES_T handleTxEndFluidBolusState( void );
-static ENDTREATMENT_STATES_T handleTxEndPausedState( void );
-
/*********************************************************************//**
* @brief
* The initTreatmentEnd function initializes the Treatment End sub-mode.
* @details \b Inputs: none
- * @details \b Outputs: treatmentEndState, txEndTimerCtr, treatmentEndPublishTimerCtr,
- * txEndEscalated, txEndAlarmRinsebackRequested, txEndAlarmEndTreatmentOnlyRequested,
- * txEndBolusRequested
+ * @details \b Outputs: treatmentEndState, txEndTimerCtr, txEndEscalated,
+ * bloodSittingTimerCtr
* @return none
*************************************************************************/
void initTreatmentEnd( void )
{
- treatmentEndState = TX_END_WAIT_FOR_RINSEBACK_STATE;
+ treatmentEndState = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE;
txEndTimerCtr = 0;
- treatmentEndPublishTimerCtr = 0;
txEndEscalated = FALSE;
+ bloodSittingTimerCtr = 0;
resetTreatmentEndFlags();
}
/*********************************************************************//**
* @brief
- * The transitionToTreatmentEnd function prepares for transition to treatment
- * end sub-mode: stops heparin delivery, bypasses the dialyzer, branches DD
- * dialysate generation based on priming fluid type, sets up Wait for Rinseback
- * actuator states, and triggers the low-priority End of Treatment alarm.
+ * The transitionToTreatmentEnd function prepares for transition to
+ * Treatment End sub-mode.
* @details \b Inputs: treatmentEndState
- * @details \b Outputs: treatmentEndState (via initTreatmentEnd), DD dialysate
- * delivery command set (via cmdBypassDialyzer/cmdStopGenerateDialysate/
- * cmdChangeQd/cmdSubstitutionRate — owned by DDInterface.c, not local to this
- * module)
+ * @details \b Outputs: none
* @return none
*************************************************************************/
void transitionToTreatmentEnd( void )
{
initTreatmentEnd();
cmdBypassDialyzer( TRUE );
stopSyringePump();
- // Set user alarm recovery actions allowed in this state
+
setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE );
setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE );
setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE );
- // Require BP door to be closed during this state
- doorClosedRequired( TRUE );
if ( FLUID_TYPE_SALINE == getFluidType() )
{
- cmdStopGenerateDialysate(); // saline branch — DD stops
+ cmdStopGenerateDialysate();
}
else
{
- // Direct DD to bypass dialysate and set substitution to universal flow rate
- cmdChangeQd( (U32)getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) ); // substitution branch — DD keeps running, Qdt=Qb
+ ///CKOE by passing the value manually suppose give 100 for substitution and check once
+ //CKOE write a print for get function
+ cmdSubstitutionRate((F32) getSysConfigTreatmentParameterU32DefaultValue( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ));
}
- // Substitution flow Off — confirmed real call (DDInterface.c). Modality scope (all vs
- // HDF-only) still needs confirmation before this is unconditional.
- // TODO CONFIRM #10: modality scope check before calling.
- cmdSubstitutionRate( 0.0F );
-
setCurrentSubState( (U32)treatmentEndState );
+ setupForTreatmentEndSubState(TREATMENT_END_WAIT_FOR_RINSEBACK_STATE);
- setupForTxEndWait4RinsebackState();
-
- // Venous bubble detection stays enabled always — confirmed real call, same pattern
- // used in ModeTreatment.c's transitionToTreatmentMode().
-#ifndef TEST_UI_ONLY
setVenousBubbleDetectionEnabled( H18_BBLD, TRUE );
-#endif
- // Trigger the low-priority End of Treatment alarm — this IS the notification (no UI dialog).
- activateAlarmNoData( ALARM_ID_TD_END_OF_TREATMENT );
+// // Trigger the low-priority End of Treatment alarm
+// activateAlarmNoData( ALARM_ID_TD_END_OF_TREATMENT );
}
/*********************************************************************//**
* @brief
- * Sets actuators for Wait for Rinseback substate entry: requires the door
- * closed, opens the arterial and venous pinch valves, commands the blood
- * pump to the End of Treatment flow rate, and continues air trap level control.
- * @details \b Inputs: none
- * @details \b Outputs: door-closed-required state, H1_VALV/H19_VALV position,
- * blood pump target rate, air trap controller start request
+ * Tracks how long blood has been sitting (not recirculating) while in
+ * Treatment End Paused substate, raising warning/max-timeout alarms as
+ * thresholds are exceeded.
+ * @details \b Alarm: ALARM_ID_TD_BLOOD_SITTING_WARNING /
+ * ALARM_ID_TD_BLOOD_SITTING_TOO_LONG as thresholds are exceeded.
+ * @details \b Inputs: bloodSittingTimerCtr
+ * @details \b Outputs: bloodSittingTimerCtr
* @return none
*************************************************************************/
-static void setupForTxEndWait4RinsebackState( void )
+static void handleTreatmentEndBloodSittingTimer( void )
{
- // Confirmed real calls/signatures from StatePreTxRecirculate.c.
- doorClosedRequired( TRUE );
+ // Ensure we do not sit in stopped state for too long (if blood in line)
+ bloodSittingTimerCtr++;
- setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN );
- setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN );
-
- // TODO CONFIRM #6: TX_END_BP_FLOW_RATE_ML_MIN is a placeholder value (150) — confirm
- // whether End of Treatment reuses TREATMENT_PARAM_BLOOD_FLOW directly (no rate change)
- // or commands a dedicated slower End-of-Treatment rate, per PRS-810 ("keep blood flowhb
- // rate at the set rate"). If PRS-810 is authoritative, replace with:
- // getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW )
- setBloodPumpTargetFlowRate( TX_END_BP_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP );
-
- // Continue air trap level control — confirmed real call (AirTrap.c). Air trap
- // controller runs continuously once started; this just (re)requests control if
- // not already controlling. No stop/start toggling needed beyond entry/pause.
- startAirTrapControl();
+ if ( FALSE == doesAlarmStatusIndicateEndTxOnly() ) // Alarms appropriate only if we are not already at an alarm stop, end Tx only
+ {
+ if ( bloodSittingTimerCtr > WARN_TIME_BLOOD_SITTING )
+ {
+ activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_WARNING );
+ }
+ if ( bloodSittingTimerCtr > MAX_TIME_BLOOD_SITTING )
+ {
+ // Activate the alarm
+ activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_TOO_LONG );
+ }
+ }
}
-
/*********************************************************************//**
* @brief
- * Sets actuators for Paused substate entry (alarm requires pump stop):
- * stops the blood pump and stops air trap level control.
+ * Applies actuator/config setup for the Treatment End substate being entered.
+ * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if newState is invalid.
* @details \b Inputs: none
- * @details \b Outputs: blood pump state (via signalBloodPumpHardStop), air trap
- * controller stop request
+ * @details \b Outputs: bloodSittingTimerCtr
+ * @param newState substate being entered
* @return none
*************************************************************************/
-static void setupForTxEndPausedState( void )
+
+static void setupForTreatmentEndSubState( TREATMENT_END_STATE_T newState )
{
- // Confirmed real call (StatePreTxRecirculate.c: handlePreTxRecirculateState() calls
- // this identically when doesAlarmStatusIndicateStop() is TRUE).
- signalBloodPumpHardStop();
+ switch ( newState )
+ {
+ case TREATMENT_END_WAIT_FOR_RINSEBACK_STATE:
+ doorClosedRequired( TRUE );
+ setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN );
+ setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN );
+ setBloodPumpTargetFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ),
+ MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP );
+ startAirTrapControl();
+ break;
- // Stop air trap level control — confirmed real call (AirTrap.c). Note:
- // endAirTrapControl() also internally calls signalLowVenousPressureCheck() to
- // keep venous pressure checking active even after auto air trap control ends.
- endAirTrapControl();
+ case TREATMENT_END_PAUSED_STATE:
+ bloodSittingTimerCtr = 0;
+ signalBloodPumpHardStop();
+ endAirTrapControl();
+ setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE );
+ setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE );
+ break;
- // Confirmed: doorClosedRequired() stays TRUE for every Treatment End substate —
- // no release call needed here. Set once at Wait for Rinseback entry and left as-is.
+ case TREATMENT_END_FLUID_BOLUS_STATE:
+ doorClosedRequired( TRUE );
+ setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN );
+ setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN );
+ setBloodPumpTargetFlowRate( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ),
+ MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP );
+ startAirTrapControl();
+ signalStartFluidBolus( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ) );
+ break;
+
+ default:
+ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_END_INVALID_STATE, (U32)newState );
+ break;
+ }
}
+
/*********************************************************************//**
* @brief
* The execTreatmentEnd function executes the Treatment End sub-mode
* state machine.
* @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if the current Treatment End
- * substate is invalid.
- * @details \b Inputs: treatmentEndState, txEndTimerCtr, txEndEscalated,
- * txEndAlarmRinsebackRequested, txEndAlarmEndTreatmentOnlyRequested,
- * txEndBolusRequested
- * @details \b Outputs: treatmentEndState, txEndTimerCtr, txEndEscalated,
- * treatmentEndPublishTimerCtr, (flags reset via resetTreatmentEndFlags)
+ * substate is invalid; ALARM_ID_TD_END_OF_TREATMENT_TIMEOUT on escalation timeout.
+ * @details \b Inputs: treatmentEndState, txEndTimerCtr, txEndEscalated
+ * @details \b Outputs: treatmentEndState, txEndTimerCtr, txEndEscalated
* @return none
*************************************************************************/
void execTreatmentEnd( void )
{
- ENDTREATMENT_STATES_T priorSubState = treatmentEndState;
+ TREATMENT_END_STATE_T priorSubState = treatmentEndState;
// Escalate low -> high alarm after confirmed 10-minute timeout, once only.
if ( ( ++txEndTimerCtr > TX_END_ESCALATION_TIMEOUT_MS ) && ( FALSE == txEndEscalated ) )
@@ -226,74 +210,60 @@
switch ( treatmentEndState )
{
- case TX_END_WAIT_FOR_RINSEBACK_STATE:
- treatmentEndState = handleTxEndWait4RinsebackState();
+ case TREATMENT_END_WAIT_FOR_RINSEBACK_STATE:
+ treatmentEndState = handleTxEndWaitForRinsebackState();
break;
- case TX_END_FLUID_BOLUS_STATE:
+ case TREATMENT_END_FLUID_BOLUS_STATE:
treatmentEndState = handleTxEndFluidBolusState();
break;
- case TX_END_PAUSED_STATE:
+ case TREATMENT_END_PAUSED_STATE:
+ handleTreatmentEndBloodSittingTimer();
treatmentEndState = handleTxEndPausedState();
break;
default:
- // Confirmed real macro/pattern (StatePreTxRecirculate.c: identical structure
- // with SW_FAULT_ID_PRE_TX_RECIRC_INVALID_STATE). Fault ID name below follows
- // the same naming convention but is not itself a confirmed enum value —
- // confirm SW_FAULT_ID_TREATMENT_END_INVALID_STATE exists before building.
SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_END_INVALID_STATE, (U32)treatmentEndState );
break;
}
if ( priorSubState != treatmentEndState )
{
- // Confirmed real pattern (StatePreTxRecirculate.c: execPreTxRecirculate()).
+ setupForTreatmentEndSubState( treatmentEndState );
setCurrentSubState( (U32)treatmentEndState );
SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_SUB_STATE_CHANGE, priorSubState, treatmentEndState );
}
-
- publishTreatmentEndData();
-
// Flags should be handled by now — reset in case not handled by current state.
resetTreatmentEndFlags();
}
/*********************************************************************//**
* @brief
- * Wait for Rinseback substate — all three user options available immediately,
- * no escalation-gating. Also handles transition to Paused if an alarm
- * requires blood pump stop.
- * @details \b Inputs: txEndAlarmRinsebackRequested, txEndAlarmEndTreatmentOnlyRequested,
- * txEndBolusRequested
- * @details \b Outputs: none (transitions reported via return value)
+ * Wait for Rinseback substate — rinseback and fluid bolus requests are
+ * available immediately, no escalation-gating. Also handles transition
+ * to Paused if an alarm requires blood pump stop.
+ * @details \b Inputs: txEndAlarmRinsebackRequested, txEndBolusRequested
+ * @details \b Outputs: none
* @return next Treatment End substate
*************************************************************************/
-static ENDTREATMENT_STATES_T handleTxEndWait4RinsebackState( void )
+
+static TREATMENT_END_STATE_T handleTxEndWaitForRinsebackState( void )
{
- ENDTREATMENT_STATES_T result = TX_END_WAIT_FOR_RINSEBACK_STATE;
+ TREATMENT_END_STATE_T result = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE;
- // Confirmed real call (StatePreTxRecirculate.c: handlePreTxRecirculateState()).
if ( TRUE == doesAlarmStatusIndicateStop() )
{
- setupForTxEndPausedState();
- result = TX_END_PAUSED_STATE;
+ result = TREATMENT_END_PAUSED_STATE;
}
else if ( TRUE == txEndAlarmRinsebackRequested )
{
- // Set via signalTreatmentEndRinsebackRequest(), called by the UI message handler
- // when the Rinseback / "Return Blood & End Treatment" option is selected.
- // PENDING: you're checking whether an existing enable/gating flag controls this
- // path before wiring the real call — hold here until confirmed. Once resolved,
- // this branch calls the real rinseback transition function (name still TBD).
+ signalTreatmentEndToRinseback();
}
-
else if ( TRUE == txEndBolusRequested )
{
- txEndPriorStateBeforeBolus = TX_END_WAIT_FOR_RINSEBACK_STATE;
- result = TX_END_FLUID_BOLUS_STATE;
- signalStartFluidBolus( TX_END_BP_FLOW_RATE_ML_MIN );
+ txEndPriorStateBeforeBolus = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE;
+ result = TREATMENT_END_FLUID_BOLUS_STATE;
}
return result;
@@ -303,24 +273,23 @@
* @brief
* Fluid Bolus substate — delegates to existing fluid bolus service.
* @details \b Inputs: none
- * @details \b Outputs: none (transitions reported via return value)
+ * @details \b Outputs: none
* @return next Treatment End substate
*************************************************************************/
-static ENDTREATMENT_STATES_T handleTxEndFluidBolusState( void )
+
+static TREATMENT_END_STATE_T handleTxEndFluidBolusState( void )
{
- ENDTREATMENT_STATES_T result = TX_END_FLUID_BOLUS_STATE;
+ TREATMENT_END_STATE_T result = TREATMENT_END_FLUID_BOLUS_STATE;
if ( FALSE == isFluidBolusActive() )
{
- result = txEndPriorStateBeforeBolus;
-
- if ( TX_END_PAUSED_STATE == txEndPriorStateBeforeBolus )
+ if ( TRUE == doesAlarmStatusIndicateStop() )
{
- setupForTxEndPausedState();
+ result= TREATMENT_END_PAUSED_STATE;
}
else
{
- setupForTxEndWait4RinsebackState();
+ result= TREATMENT_END_WAIT_FOR_RINSEBACK_STATE;
}
}
@@ -330,113 +299,178 @@
/*********************************************************************//**
* @brief
* Paused substate — entered only if an alarm requires blood pump stop.
- * Offers Rinseback and End Treatment Only directly, same as Wait for Rinseback.
- * @details \b Inputs: txEndAlarmRinsebackRequested, txEndAlarmEndTreatmentOnlyRequested
- * @details \b Outputs: none (transitions reported via return value)
+ * @details \b Inputs: none
+ * @details \b Outputs: none
* @return next Treatment End substate
*************************************************************************/
-static ENDTREATMENT_STATES_T handleTxEndPausedState( void )
+
+static TREATMENT_END_STATE_T handleTxEndPausedState( void )
{
- ENDTREATMENT_STATES_T result = TX_END_PAUSED_STATE;
+ TREATMENT_END_STATE_T result = TREATMENT_END_PAUSED_STATE;
- if ( TRUE == txEndAlarmRinsebackRequested )
- {
- // PENDING: same rinseback call as Wait for Rinseback.
- }
- else if ( TRUE == txEndAlarmEndTreatmentOnlyRequested )
- {
- // PENDING: same operation-mode-change call as Wait for Rinseback.
- }
- else if ( TRUE == txEndBolusRequested )
- {
- txEndPriorStateBeforeBolus = TX_END_PAUSED_STATE;
- result = TX_END_FLUID_BOLUS_STATE;
- signalStartFluidBolus( TX_END_BP_FLOW_RATE_ML_MIN );
- }
- else if ( FALSE == isBloodRecircBlocked() )
- {
- setupForTxEndWait4RinsebackState();
- result = TX_END_WAIT_FOR_RINSEBACK_STATE;
- }
+ if ( FALSE == isBloodRecircBlocked() )
+ {
+ result = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE;
+ }
+// else if ( TRUE == txEndAlarmRinsebackRequested )
+// {
+// signalTreatmentEndToRinseback();
+// }
+//
+// else if ( TRUE == txEndBolusRequested )
+// {
+// bloodSittingTimerCtr = 0;
+// txEndPriorStateBeforeBolus = TREATMENT_END_PAUSED_STATE;
+// result = TREATMENT_END_FLUID_BOLUS_STATE;
+// }
+
return result;
}
/*********************************************************************//**
* @brief
* Resets all Treatment End request flags.
* @details \b Inputs: none
- * @details \b Outputs: txEndAlarmRinsebackRequested, txEndAlarmEndTreatmentOnlyRequested,
- * txEndBolusRequested
+ * @details \b Outputs: txEndAlarmRinsebackRequested, txEndBolusRequested
* @return none
*************************************************************************/
+
static void resetTreatmentEndFlags( void )
{
txEndAlarmRinsebackRequested = FALSE;
- txEndAlarmEndTreatmentOnlyRequested = FALSE;
txEndBolusRequested = FALSE;
}
/*********************************************************************//**
* @brief
- * Publishes Treatment End progress to UI at set interval.
- * @details \b Inputs: treatmentEndPublishTimerCtr
- * @details \b Outputs: treatmentEndPublishTimerCtr
- * @return none
+ * The signalTreatmentEndFluidBolusRequest function signals a user request
+ * for a fluid bolus while in Treatment End.
+ * @details \b Inputs: treatmentEndState
+ * @details \b Outputs: txEndBolusRequested
+ * @return TRUE if request accepted, FALSE if rejected
*************************************************************************/
-static void publishTreatmentEndData( void )
+BOOL signalTreatmentEndFluidBolusRequest( void )
{
- if ( ++treatmentEndPublishTimerCtr >= TREATMENT_END_DATA_PUBLISH_INTERVAL )
+ BOOL result = FALSE;
+// TODO REMOVE PAUSED STATE IF W CANT ABLE TO MOVE TO RINSEBACK UPON ANY ALARMS
+ if ( ( TREATMENT_END_WAIT_FOR_RINSEBACK_STATE == treatmentEndState ) ||
+ ( TREATMENT_END_PAUSED_STATE == treatmentEndState ) )
{
- treatmentEndPublishTimerCtr = 0;
- // TODO: confirm payload contents/message ID for Treatment End status broadcast to UI.
- // You're updating this yourself once decided.
+ txEndBolusRequested = TRUE;
+ result = TRUE;
}
+
+ return result;
}
+/*********************************************************************//**
+ * @brief
+ * The getCurrentTreatmentEndState function returns the current substate of
+ * the Treatment End sub-mode.
+ * @details \b Inputs: treatmentEndState
+ * @details \b Outputs: none
+ * @return current Treatment End substate
+ *************************************************************************/
+U32 getCurrentTreatmentEndState( void )
+{
+ return (U32)treatmentEndState;
+}
+
/*********************************************************************//**
* @brief
- * Signal functions called externally (e.g. from message handlers, or from
- * ModeTreatment.c's handleTreatmentEndState() translating alarm action flags)
- * when the corresponding user action / confirmation is received. Rinseback
- * and End Treatment Only are both expected to arrive as UI messages via the
- * firmware message handler, not as locally-detected conditions.
+ * The signalTreatmentEndAlarmRinsebackUserAction function is called by
+ * ModeTreatment.c when the user has requested rinseback via an alarm
+ * recovery action while in Treatment End.
* @details \b Inputs: none
- * @details \b Outputs: txEndAlarmRinsebackRequested / txEndAlarmEndTreatmentOnlyRequested /
- * txEndBolusRequested (one each, respectively)
+ * @details \b Outputs: txEndAlarmRinsebackRequested
* @return none
*************************************************************************/
-void signalTreatmentEndRinsebackRequest( void )
+void signalTreatmentEndAlarmRinsebackUserAction( void )
{
txEndAlarmRinsebackRequested = TRUE;
}
+/*********************************************************************//**
+ * @brief
+ * The handleTxEndRinsebackUserAction function handles an end treatment
+ * rinseback user action request.
+ * @details \b Inputs: treatmentEndState
+ * @details \b Outputs: txEndAlarmRinsebackRequested
+ * @param rejReason Code indicating reason for rejection
+ * @return TRUE if user action accepted, FALSE if not
+ *************************************************************************/
-BOOL signalTreatmentEndFluidBolusRequest( void )
+static BOOL handleTxEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason )
{
BOOL result = FALSE;
- if ( ( TX_END_WAIT_FOR_RINSEBACK_STATE == treatmentEndState ) ||
- ( TX_END_PAUSED_STATE == treatmentEndState ) )
+ if ( TREATMENT_END_WAIT_FOR_RINSEBACK_STATE == treatmentEndState )
{
- txEndBolusRequested = TRUE;
result = TRUE;
+ txEndAlarmRinsebackRequested = TRUE;
}
+ else
+ {
+ *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE;
+ }
return result;
}
+
/*********************************************************************//**
* @brief
- * The getCurrentTreatmentEndState function returns the current substate of
- * the Treatment End sub-mode. Referenced by TreatmentEnd.h and expected by
- * ModeTreatment.c's broadcastTreatmentTimeAndState() (payload.txEndState).
- * @details \b Inputs: treatmentEndState
+ * The handleTreatmentEndUserAction function handles a UI Treatment End
+ * command request message.
+ * @details \b Inputs: none
* @details \b Outputs: none
- * @return current Treatment End substate
+ * @param message Incoming UI message containing the requested action.
+ * @return TRUE if request is accepted, FALSE if rejected.
*************************************************************************/
-U32 getCurrentTreatmentEndState( void )
+
+BOOL handleTreatmentEndUserAction( MESSAGE_T *message )
{
- return (U32)treatmentEndState;
+ BOOL result = FALSE;
+ U32 cmd = 0;
+ REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE;
+ UI_RESPONSE_PAYLOAD_T response;
+
+ if ( sizeof(U32) == message->hdr.payloadLen )
+ {
+ memcpy( &cmd, message->payload, sizeof(U32) );
+
+ // Reject if any alarm active — user must clear alarm first.
+ if ( FALSE == isAnyAlarmActive() )
+ {
+ switch ( (REQUESTED_TREATMENT_END_USER_ACTIONS_T)cmd )
+ {
+ case REQUESTED_USER_ACTION_TX_END_RINSEBACK_START:
+ result = handleTxEndRinsebackUserAction( &rejReason );
+ break;
+
+ default:
+ rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND;
+ break;
+ }
+ }
+ else
+ {
+ rejReason = REQUEST_REJECT_REASON_ALARM_IS_ACTIVE;
+ }
+ }
+ else
+ {
+ rejReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT;
+ }
+
+ response.accepted = result;
+ response.rejectionReason = rejReason;
+ sendMessage( MSG_ID_TD_END_TREATMENT_RESPONSE,
+ COMM_BUFFER_OUT_CAN_TD_2_UI,
+ (U08*)&response,
+ sizeof( UI_RESPONSE_PAYLOAD_T ) );
+
+ return result;
}
/**@}*/
Index: firmware/App/Modes/TreatmentEnd.h
===================================================================
diff -u -r9d80274d4f31715890d519f5f9fbe445c4614046 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 9d80274d4f31715890d519f5f9fbe445c4614046)
+++ firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -37,9 +37,10 @@
void transitionToTreatmentEnd( void );
void execTreatmentEnd( void );
U32 getCurrentTreatmentEndState( void );
-void signalTreatmentEndRinsebackRequest( void );
void signalTreatmentEndOnlyRequest( void );
BOOL signalTreatmentEndFluidBolusRequest( void );
+BOOL handleTreatmentEndUserAction( MESSAGE_T *message );
+void signalTreatmentEndAlarmRinsebackUserAction( void );
/**@}*/
Index: firmware/App/Services/Messaging.c
===================================================================
diff -u -ra1f14a4e422f94b6bc25d1b91839761e7e1196d7 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Services/Messaging.c (.../Messaging.c) (revision a1f14a4e422f94b6bc25d1b91839761e7e1196d7)
+++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -27,6 +27,7 @@
#include "Compatible.h"
#include "CpldInterface.h"
#include "DDInterface.h"
+#include "TreatmentEnd.h"
#include "Ejector.h"
#include "FluidBolus.h"
#include "FpgaTD.h"
@@ -233,6 +234,7 @@
{ MSG_ID_TD_GET_ALARM_PROPERTIES_REQUEST, &testGetAlarmPropertiesRequest },
{ MSG_ID_TD_RINSEBACK_VOLUME_OVERRIDE, &testRinsebackVolumeOverride },
{ MSG_ID_TD_RINSEBACK_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRinsebackPublishIntervalOverride },
+ { MSG_ID_TD_END_TREATMENT_REQUEST, &handleTreatmentEndUserAction },
};
/// Number of entries in the message handling function lookup table.
Index: firmware/App/Services/Messaging.h
===================================================================
diff -u -ra1f14a4e422f94b6bc25d1b91839761e7e1196d7 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Services/Messaging.h (.../Messaging.h) (revision a1f14a4e422f94b6bc25d1b91839761e7e1196d7)
+++ firmware/App/Services/Messaging.h (.../Messaging.h) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -34,6 +34,7 @@
// ********** public definitions **********
+#define SIMULATION_TEST_RINSEBACK TRUE
#define ACK_REQUIRED TRUE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver.
#define ACK_NOT_REQUIRED FALSE ///< Macro for functions that want to know if an outgoing message requires acknowledgement from receiver.
Index: firmware/App/Services/TxParams.c
===================================================================
diff -u -ra1f14a4e422f94b6bc25d1b91839761e7e1196d7 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/App/Services/TxParams.c (.../TxParams.c) (revision a1f14a4e422f94b6bc25d1b91839761e7e1196d7)
+++ firmware/App/Services/TxParams.c (.../TxParams.c) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -114,7 +114,12 @@
{ CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=2}, {.uInt=0} }, // TREATMENT_PARAM_HDF_DILUTION
{ CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=500}, {.uInt=50} }, // TREATMENT_PARAM_BLOOD_FLOW
{ CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=600}, {.uInt=50} }, // TREATMENT_PARAM_DIALYSATE_FLOW
+
+#if SIMULATION_TEST_RINSEBACK
+ { CRITICAL_DATA_TYPE_U32, {.uInt=5}, {.uInt=480}, {.uInt=60} }, // TREATMENT_PARAM_TREATMENT_DURATION
+#else
{ CRITICAL_DATA_TYPE_U32, {.uInt=60}, {.uInt=480}, {.uInt=60} }, // TREATMENT_PARAM_TREATMENT_DURATION
+#endif
{ CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=480}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_DELIVERY_DURATION
{ CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_TYPE
{ CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=5}, {.uInt=0} }, // TREATMENT_PARAM_DRY_BICARB_CART_SIZE
@@ -2215,7 +2220,14 @@
if ( TRUE == isTreatmentParamInRange( TREATMENT_PARAM_BLOOD_FLOW, requestedValue ) )
{
setTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW, request.flowRate );
- setDialysisBloodPumpFlowRate( request.flowRate );
+ if(TREATMENT_DIALYSIS_STATE == getTreatmentState() )
+ {
+ setDialysisBloodPumpFlowRate( request.flowRate );
+ }
+ else if( TREATMENT_END_STATE ==getTreatmentState() )
+ {
+ setDialysisBloodPumpFlowRateEndTx( request.flowRate );
+ }
response.accepted = TRUE;
response.rejectionReason = REQUEST_REJECT_REASON_NONE;
Index: firmware/targetConfigs/RM46L852.ccxml
===================================================================
diff -u -r73d8423edc56daed591bc0b3f7baee5540aea423 -r28d515e25f5f3b2c0bbff55abd68641927b6659c
--- firmware/targetConfigs/RM46L852.ccxml (.../RM46L852.ccxml) (revision 73d8423edc56daed591bc0b3f7baee5540aea423)
+++ firmware/targetConfigs/RM46L852.ccxml (.../RM46L852.ccxml) (revision 28d515e25f5f3b2c0bbff55abd68641927b6659c)
@@ -6,6 +6,11 @@
+
+
+
+
+