Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -rbe1f6ba8f58abfe098865c85ebca070eb0dde6ce -r679d535b77aa6722671084774ad5d96e9789e12e --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision be1f6ba8f58abfe098865c85ebca070eb0dde6ce) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -1,7 +1,25 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file ModePreTreat.c +* +* @author (last) Sean +* @date (last) 26-Nov-2025 +* +* @author (original) Sean +* @date (original) 17-Nov-2025 +* +***************************************************************************/ #include "ModePreTreat.h" #include "OperationModes.h" #include "Timers.h" +#include "TD_Defs.h" +#include "TxParams.h" /** * @addtogroup TDPreTreatmentMode @@ -12,58 +30,152 @@ // ********** private data ********** -static U32 testTimeRemove = 0; +static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + // ********** private function prototypes ********** +static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); + + /*********************************************************************//** - * @brief - * The initPreTreatmentMode function initializes the Pre Treatment Mode unit. - * @details \b Inputs: none - * @details \b Outputs: Pre Treatment Mode unit initialized. - * @return none - *************************************************************************/ +* @brief +* The initPreTreatmentMode function initializes the Pre-Treatment mode. +* @details Inputs: none +* @details Outputs: Resets the Treatment Parameters session and sets the initial +* Pre-Treatment sub-state. +* @return none +**************************************************************************/ void initPreTreatmentMode( void ) { - testTimeRemove = 0; + currentPreTreatmentState = TD_PRE_TREATMENT_CONFIRM_RX_STATE; } /*********************************************************************//** - * @brief - * The transitionToPreTreatmentMode function prepares for transition to pre-treatment - * mode. - * @details \b Inputs: none - * @details \b Outputs: none - * @return initial state - *************************************************************************/ +* @brief +* The transitionToPreTreatmentMode function prepares the system for +* entry into Pre-Treatment mode. +* @details Inputs: none +* @details Outputs: Initializes mode specific state and returns the starting +* Pre-Treatment sub-state. +* @return Initial Pre-Treatment sub-state +**************************************************************************/ U32 transitionToPreTreatmentMode( void ) { initPreTreatmentMode(); - testTimeRemove = getMSTimerCount(); + return (U32)currentPreTreatmentState; +} - return 0; +/*********************************************************************//** + * @brief + * The execPreTreatmentMode function executes the Pre-Treatment + * mode state machine. + * @details Inputs: stop button status and system conditions via helpers. + * @details Outputs: Advances the Pre-Treatment sub-state and + * previously received user confirmations. + * @return current Pre-Treatment sub-state. + *************************************************************************/ +U32 execPreTreatmentMode( void ) +{ + BOOL stop = isStopButtonPressed(); + + if ( TRUE == stop ) + { + activateAlarmNoData( ALARM_ID_TD_TREATMENT_STOPPED_BY_USER ); + } + + // Execute mode state machine + switch ( currentPreTreatmentState ) + { + case TD_PRE_TREATMENT_WATER_SAMPLE_STATE: + // currentPreTreatmentState = handleWaterSampleState(); + break; + + case TD_PRE_TREATMENT_SELF_TEST_CONSUMABLE_STATE: + // currentPreTreatmentState = handleSelfTestConsumableState(); + break; + + case TD_PRE_TREATMENT_SELF_TEST_NO_CART_STATE: + // currentPreTreatmentState = handleSelfTestNoCartState(); + break; + + case TD_PRE_TREATMENT_CART_INSTALL_STATE: + // currentPreTreatmentState = handleInstallState(); + break; + + case TD_PRE_TREATMENT_SELF_TEST_DRY_STATE: + // currentPreTreatmentState = handleSelfTestDryState(); + break; + + case TD_PRE_TREATMENT_PRIME_STATE: + // currentPreTreatmentState = handlePrimeState(); + break; + + case TD_PRE_TREATMENT_RECIRCULATE_STATE: + // currentPreTreatmentState = handleRecirculateState(); + if ( TD_PRE_TREATMENT_RECIRCULATE_STATE != currentPreTreatmentState ) + { + currentPreTreatmentState = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + } + break; + + case TD_PRE_TREATMENT_CONFIRM_RX_STATE: + // Confirm Rx step + currentPreTreatmentState = handleRxState(); + break; + + case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: + // currentPreTreatmentState = handlePatientConnectionState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); + break; + } + + return (U32)currentPreTreatmentState; } /*********************************************************************//** * @brief - * The execPreTreatmentMode function executes the Pre Treatment Mode state machine. - * @details \b Alarm: TODO fill up once the exec function is complete - * the stop button - * @details \b Inputs: TODO fill up once the exec function is complete - * @details \b Outputs: TODO fill up once the exec function is complete - * @return current state (sub-mode) + * The handleRxState function executes the Confirm Rx pre-treatment step. + * @details + * - Reads validation / confirmation / rejection flags from TxParams. + * - If the user rejected the prescription, clears the Treatment + * Parameters session and stays in Confirm Rx. + * - If the prescription is valid and confirmed, advances to the + * Patient Connection state. + * - Otherwise remains in Confirm Rx while waiting for UI action. + * @return next pre-treatment mode sub-state. *************************************************************************/ -U32 execPreTreatmentMode( void ) +static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ) { - if ( TRUE == didTimeout( testTimeRemove, 10000 ) ) // TODO temporary test code to just transition to treatment mode + BOOL paramsValid = getValidTreatParamsReceived(); + BOOL paramsConfirmed = getTreatParamsConfirmed(); + BOOL paramsRejected = getTreatParamsRejected(); + + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + + // User rejected – clear session and stay in Confirm Rx + if ( TRUE == paramsRejected ) { - requestNewOperationMode( MODE_TREA ); + resetTreatmentParameters(); + state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; } - return 0; + // Valid + confirmed – move to next step: Patient Connection + else if ( ( TRUE == paramsValid ) && ( TRUE == paramsConfirmed ) ) + { + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + } + else + { + // Still waiting on UI – remain in Confirm Rx + state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + } + return state; } /**@}*/ - Index: firmware/App/Modes/ModePreTreat.h =================================================================== diff -u -rbe1f6ba8f58abfe098865c85ebca070eb0dde6ce -r679d535b77aa6722671084774ad5d96e9789e12e --- firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision be1f6ba8f58abfe098865c85ebca070eb0dde6ce) +++ firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -1,5 +1,20 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file ModePreTreat.c +* +* @author (last) Sean +* @date (last) 26-Nov-2025 +* +* @author (original) Sean +* @date (original) 17-Nov-2025 +* +***************************************************************************/ - #ifndef __MODE_PRE_TREAT_H__ #define __MODE_PRE_TREAT_H__ @@ -20,6 +35,8 @@ U32 transitionToPreTreatmentMode( void ); // Prepares for transition to pre-treatment mode U32 execPreTreatmentMode( void ); // Execute the pre-treatment mode state machine (call from OperationModes) +TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); // Handle Confirm Rx step during Pre-Treatment + /**@}*/ #endif Index: firmware/App/Modes/ModeTxParams.c =================================================================== diff -u -r927c47388ab6bd716b857f76e2026c116dd52e69 -r679d535b77aa6722671084774ad5d96e9789e12e --- firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision 927c47388ab6bd716b857f76e2026c116dd52e69) +++ firmware/App/Modes/ModeTxParams.c (.../ModeTxParams.c) (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -569,7 +569,7 @@ { if ( FALSE == isTreatmentParamInRange( param, stagedParams[ param ] ) ) { - reasons[ param ] = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + reasons[ param ] = REQUEST_REJECT+_REASON_PARAM_OUT_OF_RANGE; result = FALSE; } else Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r9d11c51da60da3f8d2917433938a583f8a105318 -r679d535b77aa6722671084774ad5d96e9789e12e --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 9d11c51da60da3f8d2917433938a583f8a105318) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -176,6 +176,7 @@ SW_FAULT_ID_VALVES_INVALID_VALVE_ENCODER_REQ = 145, SW_FAULT_ID_TD_VALVES_INVALID_IDLE = 146, SW_FAULT_ID_TD_VALVES_INVALID_IN_TRANSITION = 147, + SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE = 148, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/DDInterface.c =================================================================== diff -u -r22a8500467c47070dff55824e2ec567c007434ce -r679d535b77aa6722671084774ad5d96e9789e12e --- firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision 22a8500467c47070dff55824e2ec567c007434ce) +++ firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -19,7 +19,7 @@ #include "MessagePayloads.h" #include "Messaging.h" #include "ModeInitPOST.h" -#include "OperationModes.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommTD.h" #include "TaskGeneral.h" @@ -36,12 +36,12 @@ // ********** private data ********** -// DD status -static DD_OP_MODE_T ddCurrentOpMode; ///< Current DD operation mode. +// DD status +static DD_OP_MODE_T ddCurrentOpMode; ///< Current DD operation mode. static U32 ddSubMode; ///< Current state (sub-mode) of current DD operation mode. static F32 dialysatePressure; ///< Current dialysate pressure reported by DD. -static BOOL ddStartCommandSent; ///< Flag indicates command to start DD has been sent. -static BOOL ddStarted; ///< Flag indicates whether we have commanded the DD to start or stop. +static BOOL ddStartCommandSent; ///< Flag indicates command to start DD has been sent. +static BOOL ddStarted; ///< Flag indicates whether we have commanded the DD to start or stop. static BOOL ddOpModeDataFreshFlag; ///< Flag to signal the handleDDOpMode() to process fresh dd op mode data. static BOOL ddDialysatePressureFreshFlag; ///< Flag to signal Index: firmware/App/Services/TxParams.c =================================================================== diff -u --- firmware/App/Services/TxParams.c (revision 0) +++ firmware/App/Services/TxParams.c (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -0,0 +1,519 @@ +/************************************************************************** +* +* Copyright (c) 2025-2025 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file TxParams.c +* +* @author (last) Sean +* @date (last) 26-Nov-2025 +* +* @author (original) Sean +* @date (original) 17-Nov-2025 +* +***************************************************************************/ + +#include "AirPump.h" +#include "AirTrap.h" +#include "BloodFlow.h" +#include "Buttons.h" +#include "Messaging.h" +#include "ModeTreatment.h" +#include "ModePreTreatment.h" +#include "OperationModes.h" +#include "Pressures.h" +#include "StateTxDialysis.h" +#include "Switches.h" +#include "TDCommon.h" +#include "TxParams.h" +#include "Utilities.h" +#include "Valve3Way.h" +#include "Valves.h" + +/** + * @addtogroup TxParams + * @{ + */ + +// ********** private definitions ********** + +#define MAX_HEPARIN_VOLUME_ML 10.0F ///< Maximum heparin volume ( in mL ) +#define NO_HEPARIN_PRE_STOP_TIME_SET 0 ///< Zero value indicates no Heparin pre-stop time was set by user +#define NO_HEPARIN_TYPE_SET 0xFFFFFFFF ///< UI will send this value for Heparin type if Heparin not used + +#define INSTIT_CHEM_DISINFECT_ENABLE_RANGE 1 ///< Institutional record chemical disinfect enable/disable allowable range + +#define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353F ///< Target syringe prime volume (in mL). TODO- move these to syringe pump controller when implemented +#define SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML 0.8F ///< Advised fill volume offset due to HW variance. + +/// Record for range and default of treatment parameters. +typedef struct +{ + CRITICAL_DATA_TYPES_T dataType; ///< Data type for the treatment parameter + CRITICAL_DATAS_T min; ///< Minimum of range + CRITICAL_DATAS_T max; ///< Maximum of range + CRITICAL_DATAS_T def; ///< Default value +} TREATMENT_PARAMS_PROPERTIES_T; + +/// Record structure for adjustable treatment parameters +typedef struct +{ + U32 bloodFlowRate_mL_min; ///< Original blood flow rate (in mL/min) set by user before treatment start + U32 dialysateFlowRate_mL_min; ///< Original dialysate flow rate (in mL/min) set by user before treatment start + U32 treatmentDuration_min; ///< Original treatment duration (in min) set by user before treatment start + S32 arterialPressureLimitWindow_mmHg; ///< Original alarm limit window for arterial pressure (in mmHg) set by user before treatment start + S32 venousPressureLimitWindow_mmHg; ///< Original alarm limit window for venous pressure (in mmHg) set by user before treatment start + S32 venousPressureLimitAsymmetric_mmHg; ///< Original alarm limit asymmetric for venous pressure (in mmHg) set by user before treatment start + S32 tmpLimitWindow_mmHg; ///< Original alarm limit window for trans-membrane pressure (in mmHg) set by user before treatment start + F32 uFVolume_L; ///< Original ultrafiltration volume (in L) set by user before treatment start +} ADJ_TREATMENT_PARAMS_T; + +#pragma pack(push, 1) +/// Record structure for response to validate Tx params +typedef struct +{ + BOOL accepted; ///< Command accepted. + U32 reason[ NUM_OF_TREATMENT_PARAMS - 1 ]; ///< Rejection reason codes; 1 for each parameter. +} TREATMENT_PARAMS_VAL_RESP_DATA_PAYLOAD_T; + +/// Record structure for response to validate ultrafiltration volume +typedef struct +{ + BOOL accepted; ///< Command accepted. + U32 rejReason; ///< Rejection reason code (if rejected). + F32 ufVolumeMl; ///< Validated ultrafiltration volume (in mL). +} UF_VOLUME_VAL_RESP_DATA_PAYLOAD_T; + +/// Record structure for set treatment parameter Dialin message. +typedef struct +{ + U32 paramID; ///< Treatment parameter ID. + CRITICAL_DATAS_T value; ///< Set value. +} DIALIN_SET_TX_PARAM_PAYLOAD_T; +#pragma pack(pop) + + +// ********** private data ********** + +static const TREATMENT_PARAMS_PROPERTIES_T TREAT_PARAMS_PROPERTIES[ NUM_OF_TREATMENT_PARAMS ] = +{ // type min max default + { 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 + { CRITICAL_DATA_TYPE_U32, {.uInt=60}, {.uInt=480}, {.uInt=60} }, // TREATMENT_PARAM_TREATMENT_DURATION + { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=300}, {.uInt=100} }, // TREATMENT_PARAM_SALINE_BOLUS_VOLUME + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=480}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_STOP_TIME + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_TYPE + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=2}, {.uInt=0} }, // TREATMENT_PARAM_ACID_CONCENTRATE + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_BICARB_CONCENTRATE + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=6}, {.uInt=0} }, // TREATMENT_PARAM_DIALYZER_TYPE + { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=60}, {.uInt=0} }, // TREATMENT_PARAM_BP_MEAS_INTERVAL + { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=300}, {.uInt=200} }, // TREATMENT_PARAM_RINSEBACK_FLOW_RATE + { CRITICAL_DATA_TYPE_U32, {.uInt=200}, {.uInt=400}, {.uInt=300} }, // TREATMENT_PARAM_RINSEBACK_VOLUME + { CRITICAL_DATA_TYPE_S32, {.sInt=120}, {.sInt=200}, {.sInt=120} }, // TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW + { CRITICAL_DATA_TYPE_S32, {.sInt=100}, {.sInt=200}, {.sInt=100} }, // TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW + { CRITICAL_DATA_TYPE_S32, {.sInt=20}, {.sInt=35}, {.sInt=20} }, // TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC + { CRITICAL_DATA_TYPE_S32, {.sInt=40}, {.sInt=100}, {.sInt=40} }, // TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW + { CRITICAL_DATA_TYPE_F32, {.sFlt=35.0}, {.sFlt=38.0}, {.sFlt=37.0} }, // TREATMENT_PARAM_DIALYSATE_TEMPERATURE + { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=1.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_HEPARIN_DISPENSE_RATE + { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=2.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME + { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=8.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_UF_VOLUME +}; + +/// Dialyzer volumes (blood and dialysate) table in mL for each type of dialyzer. +const DIALYZER_VOLUME_DATA_T dialyzerVolumeTable[ NUM_OF_DIALYZER_TYPES ] = + { { 82, 170 }, // DIALYZER_TYPE_BBRAUN_PRO_13H + { 100, 200 }, // DIALYZER_TYPE_BBRAUN_PRO_16H + { 120, 257 }, // DIALYZER_TYPE_BBRAUN_PRO_19H + { 87, 233 }, // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F160NRE + { 102, 280 }, // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F180NRE + { 113, 348 }, // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F200NRE + { 142, 304 } }; // DIALYZER_TYPE_FRESENIUS_OPTIFLUX_F250NRE + +// Current treatment parameter values +static CRITICAL_DATA_T treatmentParameters[ NUM_OF_TREATMENT_PARAMS ]; ///< Treatment parameters. +static CRITICAL_DATAS_T stagedParams[ NUM_OF_TREATMENT_PARAMS ]; ///< Temporary staged treatment parameters for validation and awaiting user confirmation. + +// Original treatment parameter values (for those that can be changed during treatment) +static ADJ_TREATMENT_PARAMS_T origTreatmentParams; ///< Originally set (before treatment) treatment parameters. + +static BOOL validTreatParamsReceived = FALSE; ///< Flag indicates user has provided treatment parameters. +static BOOL treatParamsConfirmed = FALSE; ///< Flag indicates user has confirmed the treatment parameters. +static BOOL treatParamsRejected = FALSE; ///< Flag indicates user has rejected the treatment parameters. + +// ********** private function prototypes ********** + +static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ); +static BOOL checkTreatmentParamsInRange( U32 *reasons ); +static BOOL checkTreatmentParamsDependencies( U32 *reasons ); +static void sendTreatmentParamsResponse( BOOL paramsAreInvalid, U32 *reasons ); +static void resetAllTreatmentParameters( void ); + +/*********************************************************************//** + * @brief + * The resetTreatmentParameters function resets the Treatment Parameters + * session flags and parameter values. + * @details Inputs: none + * @details Outputs: validTreatParamsReceived, treatParamsConfirmed, + * treatParamsRejected cleared and parameters reset. + * @return none + *************************************************************************/ +void resetTreatmentParameters( void ) +{ + validTreatParamsReceived = FALSE; + treatParamsConfirmed = FALSE; + treatParamsRejected = FALSE; + + resetAllTreatmentParameters(); +} + +/*********************************************************************//** +* @brief +* The getValidTreatParamsReceived function reports whether a valid set +* of Treatment Parameters has been staged. +* @details Inputs: none +* @details Outputs: none +* @return TRUE if valid parameters are available, FALSE otherwise. +**************************************************************************/ +BOOL getValidTreatParamsReceived( void ) +{ + return validTreatParamsReceived; +} + +/*********************************************************************//** + * @brief + * The getTreatParamsConfirmed function reports whether the current + * Treatment Parameters have been confirmed by the user. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the current Treatment Parameters are confirmed, + * FALSE otherwise. + *************************************************************************/ +BOOL getTreatParamsConfirmed( void ) +{ + return treatParamsConfirmed; +} + +/*********************************************************************//** + * @brief + * The getTreatParamsRejected function reports whether the current + * Treatment Parameters have been rejected by the user. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if the current Treatment Parameters are rejected, + * FALSE otherwise. + *************************************************************************/ +BOOL getTreatParamsRejected( void ) +{ + return treatParamsRejected; +} + +/*********************************************************************//** +* @brief +* Validate Treatment Parameters received from the UI. +* @details Inputs: message - UI - TD Treatment Parameters validation message. +* @details Outputs: Stages the parameters, performs range/dependency checks, +* and sends validation response including reject reasons. +* @return TRUE if parameters validated successfully, FALSE otherwise. +**************************************************************************/ +BOOL validateAndSetTreatmentParameters( MESSAGE_T *message ) +{ + BOOL paramsAreInvalid = TRUE; + BOOL paramsAreInRange, paramsAreConsistent; + BOOL result = FALSE; + TREATMENT_PARAMS_DATA_PAYLOAD_T params; + U32 rejReasons[ NUM_OF_TREATMENT_PARAMS ]; + + // Initialize reject reasons to zeroes + memset( (U08*)&rejReasons[0], 0, sizeof( U32 ) * NUM_OF_TREATMENT_PARAMS ); + + // Verify message payload length is valid + if ( sizeof( TREATMENT_PARAMS_DATA_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( ¶ms, message->payload, sizeof( TREATMENT_PARAMS_DATA_PAYLOAD_T ) ); + + // Check the received arterial and venous pressure values from the UI to be checked and capped against the min and max + // values in the institutional record + // checkPressureParamsRange( ¶ms ); // TODO + + // Extract treatment parameters from given payload to staging array so we can more easily work with them + extractTreatmentParamsFromPayload( params ); + + // Range check each treatment parameter + paramsAreInRange = checkTreatmentParamsInRange( &rejReasons[0] ); + + // Validate dependencies + paramsAreConsistent = checkTreatmentParamsDependencies( &rejReasons[0] ); + + // Determine overall validity of received treatment parameters + if ( ( TRUE == paramsAreInRange ) && ( TRUE == paramsAreConsistent ) ) + { + paramsAreInvalid = FALSE; + validTreatParamsReceived = TRUE; + } + + // Respond to set treatment parameters request message + sendTreatmentParamsResponse( paramsAreInvalid, &rejReasons[0] ); + // Send initial adjustable ranges to UI so UF volume range will be known when UF volume prompted for later + if ( TRUE == validTreatParamsReceived ) + { + U32 setTxDuration = stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt; + TREATMENT_PARAM_RANGE_BROADCAST_PAYLOAD_T payload; + + payload.minTreatmentTime = treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ].minimum.uInt; + payload.maxTreatmentTime = treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ].maximum.uInt; + payload.minUFVolume = 0.0F; + payload.maxUFVolume = MIN( (F32)setTxDuration * MAX_UF_RATE_ML_MIN, (F32)MAX_UF_VOLUME_ML ); + payload.minDialRate = treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ].minimum.uInt; + payload.maxDialRate = treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ].maximum.uInt; + sendMessage( MSG_ID_TD_TREATMENT_PARAM_RANGES, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&payload), sizeof( TREATMENT_PARAM_RANGE_BROADCAST_PAYLOAD_T ) ); + } + + result = ( TRUE == paramsAreInvalid ? FALSE : TRUE ); + } + + return result; +} +/*********************************************************************//** + * @brief + * The validateAndSetUFVolume function validates the UF volume received + * from the UI. + * @details Inputs: message – UF volume validation message. + * @details Outputs: Applies UF limits, evaluates dependent constraints, + * and sends accept / reject result back to the UI. + * @return TRUE if the UF volume is valid, FALSE otherwise. + **************************************************************************/ +BOOL validateAndSetUFVolume( MESSAGE_T *message ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + F32 uFVolumeMl; + F32 uFVolumeL; + + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + UF_VOLUME_VAL_RESP_DATA_PAYLOAD_T respPayload; + memcpy( &uFVolumeMl, message->payload, sizeof( F32 ) ); + uFVolumeL = uFVolumeMl / (F32)ML_PER_LITER; + accepted = setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, uFVolumeL ); + + if ( TRUE == accepted ) + { + U32 treatmentDuration = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + if ( treatmentDuration > 0U ) + { + F32 uFRate = uFVolumeMl / (F32)treatmentDuration; + if ( ( uFRate > MAX_UF_RATE_ML_MIN ) || ( uFRate < MIN_UF_RATE_ML_MIN ) ) + { + accepted = FALSE; + rejReason = REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE; + } + } + + else + { + accepted = FALSE; + rejReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_MINIMUM; + } + } + + else + { + rejReason = REQUEST_REJECT_REASON_UF_VOLUME_OUT_OF_RANGE; + } + + // respond to UI + uFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + uFVolumeMl = uFVolumeL * (F32)ML_PER_LITER; + respPayload.accepted = accepted; + respPayload.rejReason = rejReason; + respPayload.ufVolumeMl = uFVolumeMl; + + sendMessage( MSG_ID_TD_RESP_ULTRAFILTRATION_VOLUME_TO_VALIDATE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&respPayload), sizeof( UF_VOLUME_VAL_RESP_DATA_PAYLOAD_T ) ); + } + + return accepted; +} + +/*********************************************************************//** + * @brief + * The signalUserConfirmTreatmentParameters function handles user + * confirmation or rejection of Treatment Parameters (Rx). + * @details Inputs: message – UI confirm / reject Treatment Parameters message. + * @details Outputs: Updates local confirmation / rejection flags used by + * ModePreTreat to advance the Confirm Rx step. + * @return TRUE if the message was valid and processed, FALSE otherwise. + **************************************************************************/ +BOOL signalUserConfirmTreatmentParameters( MESSAGE_T *message ) +{ + BOOL result = FALSE; + BOOL confirmed = FALSE; + + if ( sizeof( BOOL ) == message->hdr.payloadLen ) + { + memcpy( &confirmed, message->payload, sizeof( BOOL ) ); + + if ( TRUE == confirmed ) + { + treatParamsConfirmed = TRUE; + treatParamsRejected = FALSE; + } + else + { + treatParamsConfirmed = FALSE; + treatParamsRejected = TRUE; + } + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The resetAllTreatmentParameters function resets treatment parameters + * to default values. + * @details \b Inputs: none + * @details \b Outputs: All treatment parameters reset to default values + * and original and staged treatment parameters reset to zero. + * @return none + *************************************************************************/ +static void resetAllTreatmentParameters( void ) +{ + TREATMENT_PARAM_T param; + + for ( param = TREATMENT_PARAM_FIRST_UINT; param < NUM_OF_TREATMENT_PARAMS; param++ ) + { + // Set type, range, and default value for each treatment parameter + treatmentParameters[ param ].typ = TREAT_PARAMS_PROPERTIES[ param ].dataType; + treatmentParameters[ param ].minimum = TREAT_PARAMS_PROPERTIES[ param ].min; + treatmentParameters[ param ].maximum = TREAT_PARAMS_PROPERTIES[ param ].max; + treatmentParameters[ param ].defValue = TREAT_PARAMS_PROPERTIES[ param ].def; + resetCriticalData( &treatmentParameters[ param ] ); + // Set staged parameter values to zero + stagedParams[ param ].uInt = 0; + } + + // Zero original parameter values + origTreatmentParams.bloodFlowRate_mL_min = 0; + origTreatmentParams.dialysateFlowRate_mL_min = 0; + origTreatmentParams.treatmentDuration_min = 0; + origTreatmentParams.arterialPressureLimitWindow_mmHg = 0; + origTreatmentParams.venousPressureLimitWindow_mmHg = 0; + origTreatmentParams.venousPressureLimitAsymmetric_mmHg = 0; + origTreatmentParams.tmpLimitWindow_mmHg = 0; + origTreatmentParams.uFVolume_L = 0.0F; +} + +/*********************************************************************//** + * @brief + * The checkTreatmentParamsInRange function checks whether received + * treatment parameters are in range. + * @details \b Inputs: stagedParams[] + * @details \b Outputs: reasons[] + * @param reasons Pointer to array of reject reason codes for each parameter + * @return TRUE if treatment parameters are in range, FALSE if not + *************************************************************************/ +static BOOL checkTreatmentParamsInRange( U32 *reasons ) +{ + BOOL result = TRUE; + TREATMENT_PARAM_T param; + + // Range check treatment parameters up to (but not including) UF volume + for ( param = TREATMENT_PARAM_FIRST_UINT; param < TREATMENT_PARAM_UF_VOLUME; param++ ) + { + if ( FALSE == isTreatmentParamInRange( param, stagedParams[ param ] ) ) + { + reasons[ param ] = REQUEST_REJECT+_REASON_PARAM_OUT_OF_RANGE; + result = FALSE; + } + else + { + reasons[ param ] = REQUEST_REJECT_REASON_NONE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The checkTreatmentParamsDependencies function checks dependencies between + * received treatment parameters. + * @details \b Inputs: stagedParams[] + * @details \b Outputs: reasons[] + * @param reasons Pointer to array of reject reason codes for each parameter + * @return TRUE if treatment parameter dependencies are ok, FALSE if not + *************************************************************************/ +static BOOL checkTreatmentParamsDependencies( U32 *reasons ) +{ + BOOL result = TRUE; + U32 txDur = stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt; + U32 hepST = stagedParams[ TREATMENT_PARAM_HEPARIN_STOP_TIME ].uInt; + F32 hepDR = stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_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; + + // Verify Heparin stop time is only set if Heparin dispense rate is set + if ( ( hepST > 0 ) && ( hepDR < NEARLY_ZERO ) ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_WITH_NO_DISPENSE; + result = FALSE; + } + // Verify Heparin stop time does not exceed Tx duration + else if ( hepST > txDur ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_STOP_TIME_EXCEEDS_DURATION; + result = FALSE; + } + // Verify Heparin stop time does not exceed max 10 mL Heparin volume + else if ( txVol > MAX_HEPARIN_VOLUME_ML ) + { + reasons[ TREATMENT_PARAM_HEPARIN_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_VOLUME_EXCEEDS_10_ML; + result = FALSE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The extractTreatmentParamsFromPayload function extracts the individual + * treatment parameters received from the UI into a staging array where + * they will be validated and stay until user confirms them. + * @details \b Inputs: none + * @details \b Outputs: stagedParams[] + * @param payload message payload record containing received treatment parameters + * @return none + *************************************************************************/ +static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ) +{ + // Pull treatment parameters into data array so we can more easily work with them + memcpy( &stagedParams[0], &payload, sizeof(TREATMENT_PARAMS_DATA_PAYLOAD_T) ); +} + +/*********************************************************************//** + * @brief + * The sendTreatmentParamsResponse function responds to the treatment parameters + * received from the UI. An over-all ok/rejected flag as well as individual reject + * reason codes for each parameter are provided back to the UI. + * @details \b Message \b Sent: MSG_ID_TD_RESP_TREATMENT_PARAMS_TO_VALIDATE + * @details \b Inputs : none + * @details \b Outputs : Response to treatment parameters message constructed and sent. + * @param rejected 1 if rejected, 0 if parameters ok + * @param reasons array of reject reason codes for each parameter (0=not rejected) + * @return none + *************************************************************************/ +static void sendTreatmentParamsResponse( BOOL rejected, U32 *reasons ) +{ + TREATMENT_PARAMS_VAL_RESP_DATA_PAYLOAD_T payload; + + payload.accepted = ( TRUE == rejected ? FALSE : TRUE ); + memcpy( &payload.reason[0], &reasons[0], sizeof( TREATMENT_PARAMS_DATA_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_RESP_TREATMENT_PARAMS_TO_VALIDATE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&payload), sizeof( TREATMENT_PARAMS_VAL_RESP_DATA_PAYLOAD_T ) ); +} + +/**@}*/ + + Index: firmware/App/Services/TxParams.h =================================================================== diff -u --- firmware/App/Services/TxParams.h (revision 0) +++ firmware/App/Services/TxParams.h (revision 679d535b77aa6722671084774ad5d96e9789e12e) @@ -0,0 +1,49 @@ +/************************************************************************** +* +* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file TxParams.h +* +* @author (last) Sean +* @date (last) +* +* @author (original) Sean +* @date (original) 17-Nov-2025 +* +***************************************************************************/ + +#ifndef APP_SERVICES_TXPARAMS_H_ +#define APP_SERVICES_TXPARAMS_H_ + +#include "TDCommon.h" +#include "TDDefs.h" +#include "Utilities.h" + + +/** + * @defgroup TxParams TxParams + * @brief Treatment parameters mode unit. + * + * @addtogroup TxParams + * @{ + */ + +// ********** public function prototypes **************** + +void resetTreatmentParameters( void ); // Reset all parameters to defaults +void signalUserConfirmTreatmentParameters( MESSAGE_T *message ); // Process UI confirm/reject Treatment Parameters + +BOOL validateAndSetTreatmentParameters( MESSAGE_T *message ); // Validate Treatment Parameters received from UI +BOOL validateAndSetUFVolume( MESSAGE_T *message ); // Validate UF volume received from UI + +BOOL getValidTreatParamsReceived( void ); // Determine whether valid Treatment Parameters exist +BOOL getTreatParamsConfirmed( void ); // Determine whether user confirmed the parameters +BOOL getTreatParamsRejected( void ); // Determine whether user rejected the parameters + +/**@}*/ + +#endif +