Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r1fa3d19e3ca08af7cedbf481265989830dba2627 -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 1fa3d19e3ca08af7cedbf481265989830dba2627) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -45,6 +45,11 @@ /// Initial offset used to stagger the Pre-Treatment state data broadcast. #define PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET 5U +#define PRE_TX_DEFAULT_QD_ML_MIN 400 ///< Default dialysate flow rate during recirculation when Rx is not entered in mL/min. +#define PRE_TX_INTERMEDIATE_QD_ML_MIN 300 ///< Intermediate dialysate flow rate for low prescribed Qd in mL/min. +#define PRE_TX_LOW_QD_THRESHOLD_ML_MIN 200 ///< Maximum prescribed Qd requiring the intermediate Qd transition in mL/min. +#define PRE_TX_LOW_QD_TRANSITION_TIME_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) ///< Low Qd transition time before applying the prescribed Qd in milliseconds. + // ********** private data ********** static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state @@ -53,20 +58,26 @@ static BOOL treatmentStartRequested; ///< Flag indicating the UI requested treatment start. static U32 preTreatmentStateBroadcastTimerCtr; ///< Pre-Treatment state data broadcast timer counter. static OVERRIDE_U32_T preTreatmentStatePublishInterval; ///< Pre-Treatment state data publication interval override. +static BOOL lowQdTransitionActive; ///< Flag indicating low Qd transition is active. +static U32 lowQdTransitionStartTime; ///< Start time of the low Qd transition. +static BOOL defaultQdApplied; ///< Flag indicating default Qd has been applied while Rx is unavailable. +static BOOL preTreatmentRxUpdated; ///< Flag indicating a new or updated Rx was received. // ********** private function prototypes ********** -static void setPreTreatStateTransition( void ); ///< Configure actuators and variables for Pre-Treatment state transitions. -static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); ///< Handle Install state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); ///< Handle Self Test Dry state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); ///< Handle Prime state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); ///< Handle Recirculate state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); ///< Handle Confirm Rx state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment -static void publishPreTreatmentStates( void ); ///< Publish Pre-Treatment states to the UI. +static void setPreTreatStateTransition( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); +static void handlePreTreatmentQdTransition( void ); +static void publishPreTreatmentStates( void ); + /*********************************************************************//** -* @brief +* @briefs * The initPreTreatmentMode function initializes the Pre-Treatment mode. * @details Inputs: none * @details Outputs: Initializes the Treatment Parameters session and sets the initial @@ -81,6 +92,10 @@ goToInstallStateRequested = FALSE; continueFromRecirculateRequested = FALSE; treatmentStartRequested = FALSE; + lowQdTransitionActive = FALSE; + lowQdTransitionStartTime = 0U; + defaultQdApplied = FALSE; + preTreatmentRxUpdated = FALSE; preTreatmentStateBroadcastTimerCtr = PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET; preTreatmentStatePublishInterval = (OVERRIDE_U32_T) @@ -170,6 +185,10 @@ break; } + if ( currentPreTreatmentState > TD_PRE_TREATMENT_PRIME_STATE ) + { + handlePreTreatmentQdTransition(); + } if ( prevPreTreatmentState != currentPreTreatmentState ) { setPreTreatStateTransition(); @@ -346,31 +365,50 @@ F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; F32 presUFVolumeL = 0.0F; F32 presUFRateMlMin = 0.0F; + U32 prescribedQd = 0U; + F32 prescribedDialTemp = 0.0F; + F32 ddQd = 0.0F; + F32 ddDialTemp = 0.0F; U32 ddSubMode = getDDSubMode(); TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; DD_OP_MODE_T ddOpMode = getDDOpMode(); - // Valid + confirmed – move to next state: Recirculate State + // Valid + confirmed - move to Patient Connection state if ( ( TRUE == paramsValid ) && ( TRUE == paramsConfirmed ) ) { // TODO this command of requesting dialysate delivery will move to appropriate state in pre-treatment once implemented if ( ( ddOpMode == DD_MODE_PREG ) && ( ddSubMode == DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND ) ) { presUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); presUFRateMlMin = ( presUFVolumeL * (F32)ML_PER_LITER ) / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + ddQd = (F32)prescribedQd; + ddDialTemp = prescribedDialTemp; + + if ( ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) && + ( ( TRUE == lowQdTransitionActive ) || ( TRUE == preTreatmentRxUpdated ) ) ) + { + ddQd = (F32)PRE_TX_INTERMEDIATE_QD_ML_MIN; + ddDialTemp = prescribedDialTemp + 1.0F; + } + // Direct DD to generate dialysate and bypass while priming blood - cmdStartGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFRateMlMin, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), TRUE, + cmdStartGenerateDialysate( ddQd, + presUFRateMlMin, + ddDialTemp, + TRUE, getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); } state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; - } + } - return state; + return state; } /*********************************************************************//** @@ -397,6 +435,74 @@ /*********************************************************************//** * @brief + * The handlePreTreatmentQdTransition function manages the dialysate flow + * and temperature transition after priming is complete. + * @details \b Inputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, treatment parameters. + * @details \b Outputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, dialysate flow rate, + * dialysate target temperature. + * @return none. + *************************************************************************/ +static void handlePreTreatmentQdTransition( void ) +{ + U32 prescribedQd; + F32 prescribedDialTemp; + + if ( FALSE == getValidTreatParamsReceived() ) + { + if ( FALSE == defaultQdApplied ) + { + cmdChangeQd( (F32)PRE_TX_DEFAULT_QD_ML_MIN ); + defaultQdApplied = TRUE; + } + + return; + } + + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + if ( TRUE == preTreatmentRxUpdated ) + { + preTreatmentRxUpdated = FALSE; + defaultQdApplied = FALSE; + + if ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) + { + if ( FALSE == lowQdTransitionActive ) + { + cmdChangeQd( PRE_TX_INTERMEDIATE_QD_ML_MIN ); + + lowQdTransitionStartTime = getMSTimerCount(); + lowQdTransitionActive = TRUE; + } + + cmdChangeDialysateTemperature( prescribedDialTemp + 1.0F ); + } + else + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } + } + + if ( ( TRUE == lowQdTransitionActive ) && + ( TRUE == didTimeout( lowQdTransitionStartTime, + PRE_TX_LOW_QD_TRANSITION_TIME_MS ) ) ) + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } +} + +/*********************************************************************//** + * @brief * The PreTxRequestTubeSetInstall function signals a request to transition * the Pre-Treatment mode state machine to Install state. * @details \b Inputs: none @@ -485,6 +591,19 @@ /*********************************************************************//** * @brief + * The signalPreTreatmentRxUpdated function signals that a new or updated + * treatment prescription has been received during Pre-Treatment. + * @details \b Inputs: none. + * @details \b Outputs: preTreatmentRxUpdated. + * @return none. + *************************************************************************/ +void signalPreTreatmentRxUpdated( void ) +{ + preTreatmentRxUpdated = TRUE; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. * @details \b Inputs: currentPreTreatmentState Index: firmware/App/Modes/ModePreTreat.h =================================================================== diff -u -r1fa3d19e3ca08af7cedbf481265989830dba2627 -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 1fa3d19e3ca08af7cedbf481265989830dba2627) +++ firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -41,6 +41,7 @@ void PreTxRequestContinueFromRecirculate( void ); // Request Pre-Treatment mode to transition to Confirm Rx. BOOL handleStartTreatmentRequest ( MESSAGE_T *message ); // Handle UI request to start treatment. BOOL signalPreTreatmentBackoutToStandby( void ); // Request transition from Pre-Treatment Install: Await Confirmation to Standby. +void signalPreTreatmentRxUpdated( void ); // Signal that a new or updated Rx was received. BOOL testPreTreatmentStatePublishIntervalOverride( MESSAGE_T *message ); Index: firmware/App/Modes/StatePreTxRecirculate.c =================================================================== diff -u -r2f282113c1540be57b9d00833224d7ce93d460cd -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Modes/StatePreTxRecirculate.c (.../StatePreTxRecirculate.c) (revision 2f282113c1540be57b9d00833224d7ce93d460cd) +++ firmware/App/Modes/StatePreTxRecirculate.c (.../StatePreTxRecirculate.c) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -253,7 +253,6 @@ // Direct DD to bypass dialyzer and perform no ultrafiltration cmdBypassDialyzer( TRUE ); - cmdChangeQd( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ); cmdChangeQuf( 0.0F ); } Index: firmware/App/Services/DDInterface.c =================================================================== diff -u -r1b83a4555c4040a45cecfbea45b6570812ab281e -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision 1b83a4555c4040a45cecfbea45b6570812ab281e) +++ firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -461,6 +461,36 @@ /*********************************************************************//** * @brief + * The cmdChangeDialysateTemperature function sends a generate dialysate + * command to the DD with a given new dialysate temperature. + * @details \b Inputs: none + * @details \b Outputs: dialysateDeliveryCmdSet + * @details \b Message \b Sent: Continue generate dialysate command w/ new + * dialysate temperature. + * @param dialTemp Target dialysate temperature in deg C. + * @return none + *************************************************************************/ +void cmdChangeDialysateTemperature( F32 dialTemp ) +{ + if ( TRUE == dialysateDeliveryCmdSet.start ) + { + dialysateDeliveryCmdSet.dialTemp = dialTemp; + +#ifndef TEST_UI_ONLY + sendMessage( MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA, + COMM_BUFFER_OUT_CAN_TD_2_DD, + (U08*)(&dialysateDeliveryCmdSet), + sizeof( DIALYSATE_DELIVERY_REQ_PAYLOAD_T ) ); +#endif + } + else + { + // TODO - s/w fault? + } +} + +/*********************************************************************//** + * @brief * The cmdBypassDialyzer function sends a generate dialysate command to the DD * with a given flag indicating whether dialyzer should be bypassed. * @details \b Inputs: none Index: firmware/App/Services/DDInterface.h =================================================================== diff -u -r9c833ef5623ce842267e284d958820ac0dc3a7fc -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Services/DDInterface.h (.../DDInterface.h) (revision 9c833ef5623ce842267e284d958820ac0dc3a7fc) +++ firmware/App/Services/DDInterface.h (.../DDInterface.h) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -61,6 +61,7 @@ void cmdStartGenerateDialysate( F32 qd, F32 quf, F32 dialTemp, BOOL bypass, F32 acidConvFactor, F32 bicarbConvFactor, U32 sodium, U32 bicarbonate ); void cmdChangeQd( F32 qd ); void cmdChangeQuf( F32 quf ); +void cmdChangeDialysateTemperature( F32 dialTemp ); void cmdBypassDialyzer( BOOL bypass ); void cmdStopGenerateDialysate( void ); void cmdSubstitutionRate (F32 qs ); Index: firmware/App/Services/TxParams.c =================================================================== diff -u -ra1f14a4e422f94b6bc25d1b91839761e7e1196d7 -rc34ad5cb83749cca78001409699a1fecf1436b7f --- firmware/App/Services/TxParams.c (.../TxParams.c) (revision a1f14a4e422f94b6bc25d1b91839761e7e1196d7) +++ firmware/App/Services/TxParams.c (.../TxParams.c) (revision c34ad5cb83749cca78001409699a1fecf1436b7f) @@ -487,6 +487,7 @@ BOOL paramsAreInRange, paramsAreConsistent, isUFValid; BOOL result = FALSE; BOOL paramsConfirmed = FALSE; + BOOL rxQdOrTempUpdated = FALSE; TREATMENT_PARAMS_DATA_RESPONSE_PAYLOAD_T params; U32 rejReasons[ NUM_OF_TREATMENT_PARAMS ]; @@ -524,6 +525,14 @@ TREATMENT_PARAM_T param; paramsAreInvalid = FALSE; + if ( ( FALSE == validTreatParamsReceived ) || + ( stagedParams[ TREATMENT_PARAM_DIALYSATE_FLOW ].uInt != + getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ) || + ( fabs( stagedParams[ TREATMENT_PARAM_DIALYSATE_TEMPERATURE ].sFlt - + getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ) ) >= NEARLY_ZERO ) ) + { + rxQdOrTempUpdated = TRUE; + } validTreatParamsReceived = TRUE; // direct confirmation, no validation state exists now if ( TRUE == paramsConfirmed ) { @@ -535,6 +544,10 @@ { setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ); } + if ( ( MODE_PRET == getCurrentOperationMode() ) && ( TRUE == rxQdOrTempUpdated ) ) + { + signalPreTreatmentRxUpdated(); + } // Send latest and final treatment parameters to UI sendMessage( MSG_ID_TD_VALIDATED_TREATMENT_PARAMS, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&stagedParams), sizeof( TREATMENT_PARAMS_DATA_RESPONSE_PAYLOAD_T ) ); }