/************************************************************************** * * Copyright (c) 2020-2023 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 ModeTreatmentParams.c * * @author (last) Sean Nash * @date (last) 28-Mar-2023 * * @author (original) Sean Nash * @date (original) 29-May-2020 * ***************************************************************************/ #include // For memcpy() #include "AlarmLamp.h" #include "BloodFlow.h" #include "Buttons.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "Dialysis.h" #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "SyringePump.h" #include "SystemCommMessages.h" /** * @addtogroup HDTreatmentParamsMode * @{ */ // ********** private definitions ********** #define MAX_DIALYSATE_VOLUME_ML ( 150 * ML_PER_LITER ) ///< Maximum dialysate volume (in mL) #define NO_HEPARIN_PRE_STOP_TIME_SET 0 ///< Zero value indicates no Heparin pre-stop time was set by user /// 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; // ********** private data ********** static HD_TREATMENT_PARAMS_MODE_STATE_T currentTreatmentParamsState; ///< Current state of treatment parameters mode state machine. /// Treatment parameter properties (types, ranges and defaults). const TREATMENT_PARAMS_PROPERTIES_T TREAT_PARAMS_PROPERTIES[ NUM_OF_TREATMENT_PARAMS ] = { { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=500}, {.uInt=100} }, // TREATMENT_PARAM_BLOOD_FLOW { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=600}, {.uInt=100} }, // TREATMENT_PARAM_DIALYSATE_FLOW { CRITICAL_DATA_TYPE_U32, {.uInt=60}, {.uInt=480}, {.uInt=240} }, // TREATMENT_PARAM_TREATMENT_DURATION { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=480}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME { CRITICAL_DATA_TYPE_U32, {.uInt=100}, {.uInt=300}, {.uInt=100} }, // TREATMENT_PARAM_SALINE_BOLUS_VOLUME { 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=5}, {.uInt=0} }, // TREATMENT_PARAM_DIALYZER_TYPE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=0}, {.uInt=0} }, // TREATMENT_PARAM_HEPARIN_TYPE { CRITICAL_DATA_TYPE_U32, {.uInt=0}, {.uInt=60}, {.uInt=30} }, // TREATMENT_PARAM_BP_MEAS_INTERVAL { CRITICAL_DATA_TYPE_U32, {.uInt=50}, {.uInt=150}, {.uInt=75} }, // TREATMENT_PARAM_RINSEBACK_FLOW_RATE { CRITICAL_DATA_TYPE_S32, {.sInt=-300}, {.sInt=70}, {.sInt=-300} }, // TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT { CRITICAL_DATA_TYPE_S32, {.sInt=-270}, {.sInt=100}, {.sInt=100} }, // TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT { CRITICAL_DATA_TYPE_S32, {.sInt=20}, {.sInt=270}, {.sInt=20} }, // TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT { CRITICAL_DATA_TYPE_S32, {.sInt=50}, {.sInt=300}, {.sInt=300} }, // TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT { 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=35.0}, {.sFlt=37.0}, {.sFlt=37.0} }, // TREATMENT_PARAM_DIALYSATE_TEMPERATURE { CRITICAL_DATA_TYPE_F32, {.sFlt=0.0}, {.sFlt=8.0}, {.sFlt=0.0} }, // TREATMENT_PARAM_UF_VOLUME }; // 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. static BOOL treatmentCancelled = FALSE; ///< Flag indicates user has cancelled the treatment. // ********** private function prototypes ********** static void resetAllTreatmentParameters( void ); static HD_TREATMENT_PARAMS_MODE_STATE_T handleWaitForUI2SendState( void ); static HD_TREATMENT_PARAMS_MODE_STATE_T handleWaitForUI2ConfirmState( void ); static BOOL checkTreatmentParamsInRange( U32 *reasons ); static BOOL checkTreatmentParamsDependencies( U32 *reasons ); static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ); static void sendTreatmentParamsResponse( BOOL rejected, U32 *reasons ); /*********************************************************************//** * @brief * The initOpParamsMode function initializes the Operating Parameters Mode module. * @details Inputs: none * @details Outputs: Operating Parameters Mode module initialized. * @return none *************************************************************************/ void initTreatParamsMode( void ) { currentTreatmentParamsState = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_SEND; // Reset all treatment parameters resetAllTreatmentParameters(); } /*********************************************************************//** * @brief * The transitionToOpParamsMode function prepares for transition to operating * parameters mode. * @details Inputs: none * @details Outputs: Treatment Parameters mode reset prior to starting * @return initial state *************************************************************************/ U32 transitionToTreatParamsMode( void ) { // Reset this mode initTreatParamsMode(); // Reset treatment initTreatmentMode(); initDialysis(); validTreatParamsReceived = FALSE; treatParamsConfirmed = FALSE; treatParamsRejected = FALSE; treatmentCancelled = FALSE; setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, 0.0 ); // Set user alarm recovery actions allowed in this mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, FALSE ); // Request the concentrate pumps mixing ratios and the DG fill mode prepare time cmdRequestDGMixingRatios(); return currentTreatmentParamsState; } /*********************************************************************//** * @brief * The resetAllTreatmentParameters function resets treatment parameters * to default values. * @details Inputs: none * @details Outputs: All treatment parameters reset to default values. * @return none *************************************************************************/ static void resetAllTreatmentParameters( void ) { U32 param; for ( param = 0; 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; } // NOTE: the syringe pump's monitor requires these two parameters to be set to 0 setTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME, 0.0 ); setTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE, 0.0 ); // Zero original parameter values origTreatmentParams.bloodFlowRate_mL_min = 0; origTreatmentParams.dialysateFlowRate_mL_min = 0; origTreatmentParams.treatmentDuration_min = 0; origTreatmentParams.arterialPressureLowLimit_mmHg = 0; origTreatmentParams.arterialPressureHighLimit_mmHg = 0; origTreatmentParams.venousPressureLowLimit_mmHg = 0; origTreatmentParams.venousPressureHighLimit_mmHg = 0; origTreatmentParams.uFVolume_L = 0.0; } /*********************************************************************//** * @brief * The signalUserConfirmationOfTreatmentParameters function sets the user * confirmation flag signaling user has confirmed treatment parameters. * @details Inputs: none * @details Outputs: treatParamsConfirmed * @return TRUE if confirmation accepted, FALSE if not *************************************************************************/ BOOL signalUserConfirmationOfTreatmentParameters( void ) { BOOL result = FALSE; if ( ( MODE_TPAR == getCurrentOperationMode() ) && ( HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM == currentTreatmentParamsState ) ) { treatParamsConfirmed = TRUE; result = TRUE; } return result; } /*********************************************************************//** * @brief * The signalUserRejectionOfTreatmentParameters function sets the user * rejection flag signaling user has rejected treatment parameters. * @details * Inputs : none * Outputs : treatParamsRejected * @return TRUE if rejection accepted, FALSE if not *************************************************************************/ BOOL signalUserRejectionOfTreatmentParameters( void ) { BOOL result = FALSE; if ( ( MODE_TPAR == getCurrentOperationMode() ) && ( HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM == currentTreatmentParamsState ) ) { treatParamsRejected = TRUE; result = TRUE; } return result; } /*********************************************************************//** * @brief * The signalUserCancelTreatment function sets the cancelled treatment * flag signaling the user has cancelled the treatment. * @details Inputs: none * @details Outputs: treatmentCancelled * @return TRUE if cancel accepted, FALSE if not *************************************************************************/ BOOL signalUserCancelTreatment( void ) { BOOL result = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; if ( MODE_TPAR == getCurrentOperationMode() ) { treatmentCancelled = TRUE; result = TRUE; rejReason = REQUEST_REJECT_REASON_NONE; } sendInitiateTreatmentResponseMsg( result, rejReason ); return result; } /*********************************************************************//** * @brief * The signalAlarmActionToTreatParamsMode function executes the given alarm action * as appropriate while in Treatment Parameters Mode. * @details Inputs: none * @details Outputs: given alarm action executed * @param action ID of alarm action to execute * @return none *************************************************************************/ void signalAlarmActionToTreatParamsMode( ALARM_ACTION_T action ) { // No special handling of alarm actions in this mode. } /*********************************************************************//** * @brief * The execTreatParamsMode function executes the Operating Parameters Mode state machine. * @details Inputs: treatParamsState * @details Outputs: treatParamsState * @return current state (sub-mode) *************************************************************************/ U32 execTreatParamsMode( void ) { HD_TREATMENT_PARAMS_MODE_STATE_T priorSubState = currentTreatmentParamsState; BOOL stop = isStopButtonPressed(); if ( TRUE == stop ) { // Ignore stop button in this mode. } // Execute mode state machine switch ( currentTreatmentParamsState ) { case HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_SEND: currentTreatmentParamsState = handleWaitForUI2SendState(); break; case HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM: currentTreatmentParamsState = handleWaitForUI2ConfirmState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_STATE, (U32)currentTreatmentParamsState ) break; } if ( priorSubState != currentTreatmentParamsState ) { SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, priorSubState, currentTreatmentParamsState ); } return (U32)currentTreatmentParamsState; } /*********************************************************************//** * @brief * The handleWaitForUI2SendState function handles the wait for UI to send * treatment parameters state of treatment parameters mode. * @details Inputs: * @details Outputs: * @return current state (sub-mode) *************************************************************************/ static HD_TREATMENT_PARAMS_MODE_STATE_T handleWaitForUI2SendState( void ) { HD_TREATMENT_PARAMS_MODE_STATE_T result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_SEND; if ( TRUE == treatmentCancelled ) { // Go back to standby mode requestNewOperationMode( MODE_STAN ); treatmentCancelled = FALSE; } else if ( TRUE == validTreatParamsReceived ) { // Go to wait for user confirmation state result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM; validTreatParamsReceived = FALSE; } return result; } /*********************************************************************//** * @brief * The handleWaitForUI2ConfirmState function handles the wait for UI to send * user confirmation state of treatment parameters mode. * @details Inputs: * @details Outputs: * @return current state (sub-mode) *************************************************************************/ static HD_TREATMENT_PARAMS_MODE_STATE_T handleWaitForUI2ConfirmState( void ) { HD_TREATMENT_PARAMS_MODE_STATE_T result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_CONFIRM; // If user confirms treatment parameters, set them if ( TRUE == treatParamsConfirmed ) { TREATMENT_PARAM_T param; // Set all treatment parameters (except UF volume which is not yet received) for ( param = TREATMENT_PARAM_FIRST_UINT; param < NUM_OF_TREATMENT_PARAMS; param++ ) { setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ); } // Retain original settings for treatment that may be adjusted later during treatment origTreatmentParams.bloodFlowRate_mL_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_BLOOD_FLOW ] ).uInt; origTreatmentParams.dialysateFlowRate_mL_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ] ).uInt; origTreatmentParams.treatmentDuration_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ] ).uInt; origTreatmentParams.arterialPressureLowLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ] ).sInt; origTreatmentParams.arterialPressureHighLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ] ).sInt; origTreatmentParams.venousPressureLowLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ] ).sInt; origTreatmentParams.venousPressureHighLimit_mmHg = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ] ).sInt; // If using Heparin in this treatment, set state to stopped otherwise off if ( ( stagedParams[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].sFlt > 0.0 ) || ( stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt > 0.0 ) ) { setHeparinStopped(); } else { setHeparinOff(); } // Go to pre-treatment mode requestNewOperationMode( MODE_PRET ); treatParamsConfirmed = FALSE; } else if ( TRUE == treatParamsRejected ) { treatParamsRejected = FALSE; // User rejected last parameter set, so reset them and wait for new set resetAllTreatmentParameters(); result = HD_TREATMENT_PARAMS_MODE_STATE_WAIT_4_UI_2_SEND; } else if ( TRUE == treatmentCancelled ) { treatmentCancelled = FALSE; // Go back to standby mode requestNewOperationMode( MODE_STAN ); } return result; } /*********************************************************************//** * @brief * The validateAndSetUFVolume function validates received ultrafiltration * volume treatment parameter. * @details Inputs: none * @details Outputs: * @param uFVolumeMl UF volume (in mL) from UI to validate * @return TRUE if received UF volume parameter is valid, FALSE if not *************************************************************************/ BOOL validateAndSetUFVolume( F32 uFVolumeMl ) { BOOL accepted = FALSE; REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; F32 uFVolumeL = uFVolumeMl / (F32)ML_PER_LITER; // Validate given UF volume accepted = setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, uFVolumeL ); if ( TRUE == accepted ) { U32 treatmentDuration = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); // store the user set ultrafiltration volume in pre-treatment parameters setup, if it is validated, otherwise keep the initial 0.0 origTreatmentParams.uFVolume_L = uFVolumeL; if ( treatmentDuration > 0 ) { 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 set treatment parameters request message uFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); uFVolumeMl = uFVolumeL * (F32)ML_PER_LITER; sendUFVolumeSetResponseMsg( accepted, rejReason, uFVolumeMl ); setUserSetUFVolumeStatus( accepted ); return accepted; } /*********************************************************************//** * @brief * The validateAndSetTreatmentParameters function validates received * treatment parameters. * @details Inputs: none * @details Outputs: stagedParams[], response sent * @param params payload record from treatment parameters message received from UI * @return TRUE if received treatment parameters are valid, FALSE if not *************************************************************************/ BOOL validateAndSetTreatmentParameters( TREATMENT_PARAMS_DATA_PAYLOAD_T params ) { BOOL paramsAreInvalid = TRUE; BOOL paramsAreInRange, paramsAreConsistent; U32 rejReasons[ NUM_OF_TREATMENT_PARAMS ]; // 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; sendTreatmentParamsRangesToUI( treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ].minimum.uInt, treatmentParameters[ TREATMENT_PARAM_TREATMENT_DURATION ].maximum.uInt, 0.0, MIN( (F32)setTxDuration * MAX_UF_RATE_ML_MIN, (F32)MAX_UF_VOLUME_ML ), treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ].minimum.uInt, treatmentParameters[ TREATMENT_PARAM_DIALYSATE_FLOW ].maximum.uInt ); } return !paramsAreInvalid; } /*********************************************************************//** * @brief * The checkTreatmentParamsInRange function checks whether received * treatment parameters are in range. * @details Inputs: stagedParams[] * @details 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 Inputs: stagedParams[] * @details 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 dialysateVolume_mL = stagedParams[ TREATMENT_PARAM_DIALYSATE_FLOW ].uInt * \ stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt; S32 arterialPresLimitDelta = stagedParams[ TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ].sInt - \ stagedParams[ TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ].sInt; S32 venousPresLimitDelta = stagedParams[ TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ].sInt - \ stagedParams[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ].sInt; // Check max dialysate volume dependency if ( dialysateVolume_mL > MAX_DIALYSATE_VOLUME_ML ) { reasons[ TREATMENT_PARAM_DIALYSATE_FLOW ] = REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE; reasons[ TREATMENT_PARAM_TREATMENT_DURATION ] = REQUEST_REJECT_REASON_DIAL_VOLUME_OUT_OF_RANGE; result = FALSE; } // Check Heparin pre-stop vs. treatment duration if ( stagedParams[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].uInt > stagedParams[ TREATMENT_PARAM_TREATMENT_DURATION ].uInt ) { reasons[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_PRESTOP_EXCEEDS_DURATION; result = FALSE; } // Check Heparin pre-stop vs. no Heparin delivery if ( ( stagedParams[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ].uInt > NO_HEPARIN_PRE_STOP_TIME_SET ) && ( stagedParams[ TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ].sFlt < NEARLY_ZERO ) && ( stagedParams[ TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ].sFlt < NEARLY_ZERO ) ) { reasons[ TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ] = REQUEST_REJECT_REASON_HEPARIN_PRESTOP_WITH_NO_DISPENSE; result = FALSE; } // Check arterial alarm limits dependency if ( arterialPresLimitDelta < MIN_PRESSURE_ALARM_LIMIT_DELTA_MMHG ) { reasons[ TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ] = REQUEST_REJECT_REASON_ARTERIAL_PRESSURE_LOW_VS_HIGH; reasons[ TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ] = REQUEST_REJECT_REASON_ARTERIAL_PRESSURE_LOW_VS_HIGH; result = FALSE; } // Check venous alarm limits dependency if ( venousPresLimitDelta < MIN_PRESSURE_ALARM_LIMIT_DELTA_MMHG ) { reasons[ TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ] = REQUEST_REJECT_REASON_VENOUS_PRESSURE_LOW_VS_HIGH; reasons[ TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ] = REQUEST_REJECT_REASON_VENOUS_PRESSURE_LOW_VS_HIGH; result = FALSE; } return result; } /*********************************************************************//** * @brief * The isTreatmentParamInRange function determines whether a given treatment * parameter is in range. * @details Inputs: treatParamsRanges[] * @details Outputs: none * @param param ID of parameter to check range for * @param value value of parameter to check range for * @return TRUE if given treatment parameter is in range, FALSE if not *************************************************************************/ BOOL isTreatmentParamInRange( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ) { BOOL result = FALSE; if ( param < NUM_OF_TREATMENT_PARAMS ) { if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) { if ( value.uInt >= TREAT_PARAMS_PROPERTIES[ param ].min.uInt && value.uInt <= TREAT_PARAMS_PROPERTIES[ param ].max.uInt ) { result = TRUE; } } else if ( CRITICAL_DATA_TYPE_S32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) { if ( value.sInt >= TREAT_PARAMS_PROPERTIES[ param ].min.sInt && value.sInt <= TREAT_PARAMS_PROPERTIES[ param ].max.sInt ) { result = TRUE; } } else { if ( value.sFlt >= TREAT_PARAMS_PROPERTIES[ param ].min.sFlt && value.sFlt <= TREAT_PARAMS_PROPERTIES[ param ].max.sFlt ) { result = TRUE; } } } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getS32TreatmentParamLowerRangeLimit function returns the lower range * limit for a given signed integer treatment parameter. * @details Inputs: none * @details Outputs: none * @param param ID of parameter to get lower range limit for * @return lower range limit for given signed integer treatment parameter *************************************************************************/ S32 getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_T param ) { S32 result = 0; if ( param < NUM_OF_TREATMENT_PARAMS ) { result = TREAT_PARAMS_PROPERTIES[ param ].min.sInt; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_S32_PARAM_MIN_LIMIT, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getS32TreatmentParamUpperRangeLimit function returns the upper range * limit for a given signed integer treatment parameter. * @details Inputs: none * @details Outputs: none * @param param ID of parameter to get upper range limit for * @return upper range limit for given signed integer treatment parameter *************************************************************************/ S32 getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_T param ) { S32 result = 0; if ( param < NUM_OF_TREATMENT_PARAMS ) { result = TREAT_PARAMS_PROPERTIES[ param ].max.sInt; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_S32_PARAM_MAX_LIMIT, (U32)param ) } 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 Inputs: none * @details 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 * Inputs : none * 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 ) { BOOL accepted = ( TRUE == rejected ? FALSE : TRUE ); U32 respPayload[NUM_OF_TREATMENT_PARAMS]; memcpy( &respPayload[0], &reasons[0], sizeof(TREATMENT_PARAMS_DATA_PAYLOAD_T) ); sendTreatmentParametersResponseMsg( accepted, (U08*)(&respPayload[0]), ( NUM_OF_TREATMENT_PARAMS - 1 ) ); // UF vol. param not included in reject reasons } /*********************************************************************//** * @brief * The setTreatmentParameterU32 function sets a given unsigned integer * treatment parameter to a given value. * @details Inputs: treatmentParameters[] * @details Outputs: treatmentParameters[] * @param param ID of treatment parameter to set unsigned integer value for * @param value unsigned integer value to assign to given treatment parameter * @return TRUE if set was successful, FALSE if not *************************************************************************/ BOOL setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ) { BOOL result = FALSE; // Validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.uInt = value; result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_U32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The setTreatmentParameterS32 function sets a given signed integer treatment * parameter to a given value. * @details Inputs: treatmentParameters[] * @details Outputs: treatmentParameters[] * @param param ID of treatment parameter to set signed integer value for * @param value signed integer value to assign to given treatment parameter * @return TRUE if set was successful, FALSE if not *************************************************************************/ BOOL setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ) { BOOL result = FALSE; // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.sInt = value; result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_S32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The setTreatmentParameterF32 sets a given floating point treatment parameter * to a given value. * @details Inputs: treatmentParameters[] * @details Outputs: treatmentParameters[] * @param param ID of treatment parameter to set floating point value for * @param value floating point value to assign to given treatment parameter * @return TRUE if set was successful, FALSE if not *************************************************************************/ BOOL setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ) { BOOL result = FALSE; // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.sFlt = value; result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_F32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getTreatmentParameterU32 function gets the value of a given unsigned * integer treatment parameter. * @details Inputs: treatmentParameters[] * @details Outputs: none * @param param ID of treatment parameter to get unsigned integer value for * @return value of given unsigned integer treatment parameter *************************************************************************/ U32 getTreatmentParameterU32( TREATMENT_PARAM_T param ) { U32 result = 1; // Validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); result = data.uInt; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_U32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getTreatmentParameterS32 function gets the value of a given signed * integer treatment parameter. * @details Inputs: treatmentParameters[] * @details Outputs: none * @param param ID of treatment parameter to get signed integer value for * @return value of given signed integer treatment parameter *************************************************************************/ S32 getTreatmentParameterS32( TREATMENT_PARAM_T param ) { S32 result = 1; // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); result = data.sInt; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_S32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getTreatmentParameterF32 function gets the value of a given floating point * treatment parameter. * @details Inputs: treatmentParameters[] * @details Outputs: none * @param param ID of treatment parameter to get floating point value for * @return value of given floating point treatment parameter *************************************************************************/ F32 getTreatmentParameterF32( TREATMENT_PARAM_T param ) { F32 result = 1.0; // Validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { CRITICAL_DATAS_T data = getCriticalData( &treatmentParameters[ param ] ); result = data.sFlt; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_F32_PARAM, (U32)param ) } return result; } /*********************************************************************//** * @brief * The getUltrafiltrationVolumeOriginal function gets the floating point value * of the original set treatment parameter's ultrafiltration volume by user in * Pre-Treatment mode. * @details Inputs: none * @details Outputs: origTreatmentParams.uFVolume_L * @param none * @return the original ultrafiltration volume value in liter *************************************************************************/ F32 getUltrafiltrationVolumeOriginal( void ) { return origTreatmentParams.uFVolume_L; } /*********************************************************************//** * @brief * The getUltrafiltrationRateOriginal function gets the floating point value * of the original ultrafiltration rate calculated by the set treatment parameter's * ultrafiltration volume and treatment duration by user in Pre-Treatment mode. * @details Inputs: origTreatmentParams.uFVolume_L, origTreatmentParams.treatmentDuration_min * @details Outputs: none * @param none * @return the original ultrafiltration rate value in mL/min *************************************************************************/ F32 getUltrafiltrationRateOriginal( void ) { return ( ( origTreatmentParams.uFVolume_L * ML_PER_LITER ) / origTreatmentParams.treatmentDuration_min ); } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetTreatmentParameterOverride function overrides the value of a * given treatment parameter. * @details Inputs: none * @details Outputs: treatment parameter set to given value * @param param ID of treatment parameter to set value of * @param value value to set for given treatment parameter * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTreatmentParameter( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ) { BOOL result = FALSE; if ( param < NUM_OF_TREATMENT_PARAMS ) { if ( TRUE == isTestingActivated() ) { // Set parameter per its type if ( CRITICAL_DATA_TYPE_U32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) { result = setTreatmentParameterU32( param, value.uInt ); } else if ( CRITICAL_DATA_TYPE_S32 == TREAT_PARAMS_PROPERTIES[ param ].dataType ) { result = setTreatmentParameterS32( param, value.sInt ); } else { result = setTreatmentParameterF32( param, value.sFlt ); } } } return result; } /*********************************************************************//** * @brief * The testUpdateCurrentTreatmentParameters function pulls the current * treatment parameters from the critical section if data has been * determined to be valid. Calls sendTestCurrentTreatmentParametersResponse. * @details Inputs: none * @details Outputs: CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T containing * treatment parameters. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSendCurrentTreatmentParameters( void ) { BOOL result = FALSE; CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T current_treatment_params; if ( TRUE == isTestingActivated() ) { // Test one parameter for set since all parameters are set after parameter validation. if ( TRUE == isCriticalDataSet( &treatmentParameters[ TREATMENT_PARAM_BLOOD_FLOW ] ) ) { result = TRUE; current_treatment_params.accepted = TRUE; current_treatment_params.treatment_parameters.bloodFlowRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); current_treatment_params.treatment_parameters.dialysateFlowRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); current_treatment_params.treatment_parameters.treatmentDuration_min = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); current_treatment_params.treatment_parameters.heparinPreStop_min = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); current_treatment_params.treatment_parameters.salineBolusVolume_mL = getTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); current_treatment_params.treatment_parameters.acidConcentrate = getTreatmentParameterU32( TREATMENT_PARAM_ACID_CONCENTRATE ); current_treatment_params.treatment_parameters.bicarbConcentrate = getTreatmentParameterU32( TREATMENT_PARAM_BICARB_CONCENTRATE ); current_treatment_params.treatment_parameters.dialyzerType = getTreatmentParameterU32( TREATMENT_PARAM_DIALYZER_TYPE ); current_treatment_params.treatment_parameters.heparinType = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_TYPE ); current_treatment_params.treatment_parameters.bloodPressureMeasurementInterval_min = getTreatmentParameterU32( TREATMENT_PARAM_BP_MEAS_INTERVAL ); current_treatment_params.treatment_parameters.rinsebackFlowRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ); current_treatment_params.treatment_parameters.arterialPressureLowLimit_mmHg = getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); current_treatment_params.treatment_parameters.arterialPressureHighLimit_mmHg = getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); current_treatment_params.treatment_parameters.venousPressureLowLimit_mmHg = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ); current_treatment_params.treatment_parameters.venousPressureHighLimit_mmHg = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ); current_treatment_params.treatment_parameters.heparinDispenseRate_mL_hr = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); current_treatment_params.treatment_parameters.heparinBolusVolume_mL = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); current_treatment_params.treatment_parameters.dialysateTemperature_degC = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); current_treatment_params.uFVolume_L = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); } else { current_treatment_params.accepted = FALSE; current_treatment_params.treatment_parameters.bloodFlowRate_mL_min = 0; current_treatment_params.treatment_parameters.dialysateFlowRate_mL_min = 0; current_treatment_params.treatment_parameters.treatmentDuration_min = 0; current_treatment_params.treatment_parameters.heparinPreStop_min = 0; current_treatment_params.treatment_parameters.salineBolusVolume_mL = 0; current_treatment_params.treatment_parameters.acidConcentrate = 0; current_treatment_params.treatment_parameters.bicarbConcentrate = 0; current_treatment_params.treatment_parameters.dialyzerType = 0; current_treatment_params.treatment_parameters.heparinType = 0; current_treatment_params.treatment_parameters.bloodPressureMeasurementInterval_min = 0; current_treatment_params.treatment_parameters.rinsebackFlowRate_mL_min = 0; current_treatment_params.treatment_parameters.arterialPressureLowLimit_mmHg = 0; current_treatment_params.treatment_parameters.arterialPressureHighLimit_mmHg = 0; current_treatment_params.treatment_parameters.venousPressureLowLimit_mmHg = 0; current_treatment_params.treatment_parameters.venousPressureHighLimit_mmHg = 0; current_treatment_params.treatment_parameters.heparinDispenseRate_mL_hr = 0; current_treatment_params.treatment_parameters.heparinBolusVolume_mL = 0; current_treatment_params.treatment_parameters.dialysateTemperature_degC = 0; current_treatment_params.uFVolume_L = 0; } sendTestCurrentTreatmentParametersResponse(current_treatment_params); } return result; } /**@}*/