Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -44,8 +44,6 @@ #define MAX_TREATMENT_TIME_MINUTES ( 8 * MIN_PER_HOUR ) ///< Maximum treatment time (in minutes). #define MIN_TREATMENT_TIME_MINUTES ( 1 * MIN_PER_HOUR ) ///< Minimum treatment time (in minutes). -#define MAX_BOLUS_VOLUME_ML ( 300 ) ///< Minimum fluid bolus volume (in mL). -#define MIN_BOLUS_VOLUME_ML ( 100 ) ///< Maximum fluid bolus volume (in mL). /// Interval (ms/task time) at which the treatment time data is published on the CAN bus. #define TREATMENT_TIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) @@ -822,229 +820,6 @@ /*********************************************************************//** * @brief - * The validateAndSetTreatmentDuration function handles the UI treatment - * duration validation request during Treatment mode. - * @details \b Message \b Sent: MSG_ID_TD_DURATION_VALIDATE_RESPONSE - * @details \b Inputs: message containing requested treatment duration. - * @details \b Outputs: response updated with acceptance status, rejection - * reason, duration, UF volume goal, and UF rate. - * @return TRUE if response message is sent successfully, FALSE otherwise. - *************************************************************************/ -BOOL validateAndSetTreatmentDuration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - DURATION_VALIDATE_REQUEST_PAYLOAD_T request; - DURATION_VALIDATE_RESPONSE_PAYLOAD_T response; - F32 elapsedTreatmentTimeMin = 0.0F; - F32 measuredUFVolumeL = 0.0F; - F32 remainingUFVolumeL = 0.0F; - F32 remainingTreatmentTimeHr = 0.0F; - F32 newUfRateLHr = 0.0F; - - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; - response.duration = 0; - response.ufVolumeGoal = 0.0F; - response.ufRate = 0.0F; - - if ( message->hdr.payloadLen == sizeof( DURATION_VALIDATE_REQUEST_PAYLOAD_T ) ) - { - memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); - - response.rejectionReason = REQUEST_REJECT_REASON_NONE; - response.duration = request.duration; - - if ( ( request.duration >= MIN_TREATMENT_TIME_MINUTES ) && - ( request.duration <= MAX_TREATMENT_TIME_MINUTES ) ) - { - elapsedTreatmentTimeMin = (F32)treatmentTimeMS / (F32)MS_PER_SECOND / (F32)SEC_PER_MIN; - - if ( (F32)request.duration <= elapsedTreatmentTimeMin ) - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; - } - else - { - measuredUFVolumeL = getUltrafiltrationVolumeDrawn(); - remainingUFVolumeL = presUFVolumeL - measuredUFVolumeL; - - if ( remainingUFVolumeL < 0.0F ) - { - remainingUFVolumeL = 0.0F; - } - - remainingTreatmentTimeHr = ( (F32)request.duration - elapsedTreatmentTimeMin ) / (F32)MIN_PER_HOUR; - - if ( remainingTreatmentTimeHr > 0.0F ) - { - newUfRateLHr = remainingUFVolumeL / remainingTreatmentTimeHr; - - response.ufVolumeGoal = presUFVolumeL; - response.ufRate = newUfRateLHr; - - if ( newUfRateLHr <= 2.0F ) - { - response.accepted = TRUE; - } - else - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE; - } - } - else - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; - } - } - } - else - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; - } - } - - result = sendMessage( MSG_ID_TD_DURATION_VALIDATE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); - - return result; -} - -/*********************************************************************//** - * @brief - * The signalUserConfirmationOfTreatmentDuration function handles the UI - * treatment duration confirmation request during Treatment mode. - * @details \b Message \b Sent: MSG_ID_TD_DURATION_CONFIRM_RESPONSE - * @details \b Inputs: message containing confirmed treatment duration. - * @details \b Outputs: response updated with acceptance status, rejection - * reason, duration, and UF volume. - * @return TRUE if response message is sent successfully, FALSE otherwise. - *************************************************************************/ -BOOL signalUserConfirmationOfTreatmentDuration( MESSAGE_T *message ) -{ - BOOL result = FALSE; - DURATION_CONFIRM_REQUEST_PAYLOAD_T request; - TREATMENT_TIME_CHANGE_RESPONSE_PAYLOAD_T response; - F32 elapsedTreatmentTimeMin = 0.0F; - F32 measuredUFVolumeL = 0.0F; - F32 remainingUFVolumeL = 0.0F; - F32 remainingTreatmentTimeHr = 0.0F; - - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; - response.duration = 0; - response.volume = 0.0F; - - if ( message->hdr.payloadLen == sizeof( DURATION_CONFIRM_REQUEST_PAYLOAD_T ) ) - { - memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); - - response.rejectionReason = REQUEST_REJECT_REASON_NONE; - response.duration = request.duration; - response.volume = presUFVolumeL; - - if ( ( request.duration >= MIN_TREATMENT_TIME_MINUTES ) && - ( request.duration <= MAX_TREATMENT_TIME_MINUTES ) ) - { - elapsedTreatmentTimeMin = (F32)treatmentTimeMS / (F32)MS_PER_SECOND / (F32)SEC_PER_MIN; - - if ( (F32)request.duration <= elapsedTreatmentTimeMin ) - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; - } - else - { - measuredUFVolumeL = getUltrafiltrationVolumeDrawn(); - remainingUFVolumeL = presUFVolumeL - measuredUFVolumeL; - - if ( remainingUFVolumeL < 0.0F ) - { - remainingUFVolumeL = 0.0F; - } - - remainingTreatmentTimeHr = ( (F32)request.duration - elapsedTreatmentTimeMin ) / (F32)MIN_PER_HOUR; - - if ( remainingTreatmentTimeHr > 0.0F ) - { - presTreatmentTimeSecs = request.duration * SEC_PER_MIN; - presUFRateLHr = remainingUFVolumeL / remainingTreatmentTimeHr; - - setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, request.duration ); - - setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), - presUFVolumeL, - presUFRateLHr ); - - response.accepted = TRUE; - } - else - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; - } - } - } - else - { - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; - } - } - - result = sendMessage( MSG_ID_TD_DURATION_CONFIRM_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); - - return result; -} - -/*********************************************************************//** - * @brief - * The validateAndSetBolusVolume function handles the UI fluid bolus - * volume change request during Treatment mode. - * @details \b Message \b Sent: MSG_ID_TD_BOLUS_VOLUME_CHANGE_RESPONSE - * @details \b Inputs: message containing requested bolus volume. - * @details \b Outputs: response updated with acceptance status, - * rejection reason, and bolus volume. - * @return TRUE if response message is sent successfully, FALSE otherwise. - *************************************************************************/ -BOOL validateAndSetBolusVolume( MESSAGE_T *message ) -{ - BOOL result = FALSE; - BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T request; - BOLUS_VOLUME_CHANGE_RESPONSE_PAYLOAD_T response; - - response.accepted = FALSE; - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; - response.bolusVolume = 0U; - - if ( message->hdr.payloadLen == sizeof( BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T ) ) - { - memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); - - response.bolusVolume = request.bolusVolume; - - if ( ( request.bolusVolume >= MIN_BOLUS_VOLUME_ML ) && - ( request.bolusVolume <= MAX_BOLUS_VOLUME_ML ) ) - { - response.accepted = TRUE; - response.rejectionReason = REQUEST_REJECT_REASON_NONE; - - // TODO: Add state validation and apply bolus volume when saline bolus feature is integrated. - } - else - { - response.rejectionReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; - } - } - - result = sendMessage( MSG_ID_TD_BOLUS_VOLUME_CHANGE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); - - return result; -} -/*********************************************************************//** - * @brief * The broadcastTreatmentTimeAndState function broadcasts treatment time and * state data during treatment. * @details \b Inputs: treatmentTimeBroadcastTimerCtr, elapsedTreatmentTimeInSecs, Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -101,9 +101,6 @@ void signalAlarmActionToTreatmentMode( ALARM_ACTION_T action ); // Execute alarm action as appropriate for treatment mode void signalEndTreatment( void ); // Requesting transition to post-treatment mode void signalBloodPrimeToDialysis( void ); // Blood prime sub-mode is signaling to move on to dialysis sub-mode -BOOL validateAndSetTreatmentDuration( MESSAGE_T *message ); // Validate duration request and compute UF rate -BOOL signalUserConfirmationOfTreatmentDuration( MESSAGE_T *message );// Apply confirmed duration and update runtime settings -BOOL validateAndSetBolusVolume( MESSAGE_T *message ); // Validate bolus volume request and update parameter void broadcastTreatmentTimeAndState( void ); // Broadcast the times and states of this treatment Index: firmware/App/Modes/StateTxDialysis.c =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -252,79 +252,79 @@ response.rejectionReason = REQUEST_REJECT_REASON_NONE; // Verify payload length is valid - if ( sizeof( U32 ) == message->hdr.payloadLen ) + if ( sizeof( BOOL ) == message->hdr.payloadLen ) { - U32 requestedState = 0U; + BOOL requestedState = FALSE; - memcpy( &requestedState, message->payload, sizeof( U32 ) ); + memcpy( &requestedState, message->payload, sizeof( requestedState ) ); // Handle request to resume ultrafiltration - if ( requestedState == 0U ) + if ( requestedState == FALSE ) { - if ( ( MODE_TREA == currMode ) && ( TREATMENT_DIALYSIS_STATE == trtState ) && ( DIALYSIS_UF_PAUSED_STATE == currentDialysisState ) ) + if ( ( MODE_TREA == currMode ) && + ( TREATMENT_DIALYSIS_STATE == trtState ) && + ( DIALYSIS_UF_PAUSED_STATE == currentDialysisState ) ) { ufResumeRequested = TRUE; response.accepted = TRUE; - if ( setUFRateLHr > 0.0 ) + + if ( setUFRateLHr > 0.0F ) { - //sendTreatmentLogEventData( UF_START_RESUME_EVENT, 0.0, setUFRateLHr ); + // sendTreatmentLogEventData( UF_START_RESUME_EVENT, 0.0F, setUFRateLHr ); } } + else if ( MODE_TREA != currMode ) + { + response.rejectionReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; + } + else if ( TREATMENT_DIALYSIS_STATE != trtState ) + { + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; + } else { - if ( MODE_TREA != currMode ) - { - response.rejectionReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; - } - else if ( TREATMENT_DIALYSIS_STATE != trtState ) - { - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; - } - else - { - response.rejectionReason = REQUEST_REJECT_REASON_UF_NOT_PAUSED; - } + response.rejectionReason = REQUEST_REJECT_REASON_UF_NOT_PAUSED; } } // Handle request to pause ultrafiltration - else if ( requestedState == 1U ) + else if ( requestedState == TRUE ) { - if ( ( MODE_TREA == currMode ) && ( TREATMENT_DIALYSIS_STATE == trtState ) && ( DIALYSIS_UF_STATE == currentDialysisState ) ) + if ( ( MODE_TREA == currMode ) && + ( TREATMENT_DIALYSIS_STATE == trtState ) && + ( DIALYSIS_UF_STATE == currentDialysisState ) ) { ufPauseRequested = TRUE; response.accepted = TRUE; + if ( setUFRateLHr > 0.0F ) { - //sendTreatmentLogEventData( UF_PAUSE_EVENT, setUFRateLHr, 0.0 ); + // sendTreatmentLogEventData( UF_PAUSE_EVENT, setUFRateLHr, 0.0F ); } } + else if ( MODE_TREA != currMode ) + { + response.rejectionReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; + } + else if ( TREATMENT_DIALYSIS_STATE != trtState ) + { + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; + } else { - if ( MODE_TREA != currMode ) - { - response.rejectionReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; - } - else if ( TREATMENT_DIALYSIS_STATE != trtState ) - { - response.rejectionReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; - } - else - { - response.rejectionReason = REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS; - } + response.rejectionReason = REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS; } } else - { - response.rejectionReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; - } - } - else { - response.rejectionReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + response.rejectionReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; } + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + } - // Send response w/ reason code if rejected + // Send response sendMessage( MSG_ID_TD_UF_PAUSE_RESUME_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)(&response), sizeof( UI_RESPONSE_PAYLOAD_T ) ); return response.accepted; Index: firmware/App/Monitors/Pressures.c =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -47,23 +47,6 @@ #define PRES_LIMIT_SHORT_STABILIZE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Duration of pressure limit short stabilization period (in ms). #define PRES_LIMIT_RESTABILIZE_TIME_MS ( 15 * SEC_PER_MIN * MS_PER_SECOND ) ///< Duration of pressure limit re-stabilize period (in ms). -// Pressure limit window validation ranges (UI-editable values as per PRS) -#define ART_PRESSURE_LIMIT_WINDOW_MIN_MMHG ( 120 ) ///< Minimum arterial pressure window limit (mmHg) -#define ART_PRESSURE_LIMIT_WINDOW_MAX_MMHG ( 200 ) ///< Maximum arterial pressure window limit (mmHg) -#define ART_PRESSURE_LIMIT_WINDOW_STEP_MMHG ( 40 ) ///< Arterial pressure window increment (mmHg) - -#define VEN_PRESSURE_LIMIT_WINDOW_MIN_MMHG ( 100 ) ///< Minimum venous pressure window limit (mmHg) -#define VEN_PRESSURE_LIMIT_WINDOW_MAX_MMHG ( 200 ) ///< Maximum venous pressure window limit (mmHg) -#define VEN_PRESSURE_LIMIT_WINDOW_STEP_MMHG ( 20 ) ///< Venous pressure window increment (mmHg) - -#define VEN_ASYM_PRESSURE_LIMIT_WINDOW_MIN_MMHG ( 20 ) ///< Minimum venous asymmetric pressure limit (mmHg) -#define VEN_ASYM_PRESSURE_LIMIT_WINDOW_MAX_MMHG ( 35 ) ///< Maximum venous asymmetric pressure limit (mmHg) -#define VEN_ASYM_PRESSURE_LIMIT_WINDOW_STEP_MMHG ( 5 ) ///< Venous asymmetric pressure increment (mmHg) - -#define TMP_PRESSURE_LIMIT_WINDOW_MIN_MMHG ( 40 ) ///< Minimum TMP pressure window limit (mmHg) -#define TMP_PRESSURE_LIMIT_WINDOW_MAX_MMHG ( 100 ) ///< Maximum TMP pressure window limit (mmHg) -#define TMP_PRESSURE_LIMIT_WINDOW_STEP_MMHG ( 20 ) ///< TMP pressure window increment (mmHg) - /// Pressure Limit minimum stabilization time before short stabilization time activation static const U32 PRES_LIMIT_MIN_STABILIZATION_TIME_IN_MS = ( PRES_LIMIT_STABILIZATION_TIME_MS - PRES_LIMIT_SHORT_STABILIZE_TIME_MS ); @@ -231,10 +214,6 @@ static void determineArtVenPressureLimits( void ); static void filterInlinePressureReadings( F32 artPres, F32 venPres, F32 tmpPres ); static void filterBaroPressureReadings( F32 baroPresPSI ); -static BOOL isArterialPressureLimitWindowValid( S32 value ); -static BOOL isVenousPressureLimitWindowValid( S32 value ); -static BOOL isVenousAsymmetricPressureLimitWindowValid( S32 value ); -static BOOL isTmpPressureLimitWindowValid( S32 value ); /*********************************************************************//** * @brief @@ -1270,154 +1249,6 @@ return result; } -/*********************************************************************//** -* @brief -* The pressureLimitHandleChangeRequest function validates pressure limit -* change request received from the UI. -* @details \b Message \b Received: MSG_ID_UI_PRESSURE_LIMITS_CHANGE_REQUEST -* @details \b Message \b Sent: MSG_ID_TD_PRESSURE_LIMITS_CHANGE_RESPONSE -* @details \b Inputs: arterial, venous, venous asymmetric, and TMP -* pressure limit window values -* @details \b Outputs: pressure limits updated when valid -* @param message set message from UI -* @return TRUE if request is valid, FALSE if not -*************************************************************************/ -BOOL pressureLimitHandleChangeRequest ( MESSAGE_T *message ) -{ - BOOL result = FALSE; - REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; - PRESSURE_LIMIT_CHANGE_REQUEST_T request = { 0 }; - PRESSURE_LIMIT_CHANGE_RESPONSE_T response = { 0 }; - - if ( message->hdr.payloadLen == sizeof( request ) ) - { - memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); - - if ( isArterialPressureLimitWindowValid( request.arterialPressureLimitWindowMMHG ) && - isVenousPressureLimitWindowValid( request.venousPressureLimitWindowMMHG ) && - isVenousAsymmetricPressureLimitWindowValid( request.venousAsymmetricPressureLimitWindowMMHG ) && - isTmpPressureLimitWindowValid( request.tmpPressureLimitWindowMMHG ) ) - { - setTreatmentParameterS32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, - request.arterialPressureLimitWindowMMHG ); - - setTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, - request.venousPressureLimitWindowMMHG ); - - setTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, - request.venousAsymmetricPressureLimitWindowMMHG ); - - setTreatmentParameterS32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW, - request.tmpPressureLimitWindowMMHG ); - - updatePressureLimitWindows(); - - result = TRUE; - rejReason = REQUEST_REJECT_REASON_NONE; - } - else - { - result = FALSE; - rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; - } - } - - response.accepted = result; - response.rejectionReason = rejReason; - response.arterialPressureLimitWindowMMHG = request.arterialPressureLimitWindowMMHG; - response.venousPressureLimitWindowMMHG = request.venousPressureLimitWindowMMHG; - response.venousAsymmetricPressureLimitWindowMMHG = request.venousAsymmetricPressureLimitWindowMMHG; - response.tmpPressureLimitWindowMMHG = request.tmpPressureLimitWindowMMHG; - - sendMessage( MSG_ID_TD_PRESSURE_LIMITS_CHANGE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, - sizeof( response ) ); - - return result; -} - -/*********************************************************************//** - * @brief - * The isPressureLimitValueValid function checks whether a pressure limit - * value is within the specified range and aligns with the defined step. - * @details \b Inputs: value, minValue, maxValue, stepValue - * @details \b Outputs: none - * @return TRUE if value is valid, FALSE otherwise - *************************************************************************/ -static BOOL isPressureLimitValueValid( S32 value, S32 minValue, S32 maxValue, S32 stepValue ) -{ - BOOL result = FALSE; - - if ( ( value >= minValue ) && ( value <= maxValue ) ) - { - result = ( ( ( value - minValue ) % stepValue ) == 0 ); - } - - return result; -} - -/*********************************************************************//** - * @brief - * The isArterialPressureLimitWindowValid function checks whether the - * arterial pressure limit window value is within valid range. - * @details \b Inputs: value - * @details \b Outputs: none - * @return TRUE if value is valid, FALSE otherwise - *************************************************************************/ -static BOOL isArterialPressureLimitWindowValid( S32 value ) -{ - return isPressureLimitValueValid( value, - ART_PRESSURE_LIMIT_WINDOW_MIN_MMHG, - ART_PRESSURE_LIMIT_WINDOW_MAX_MMHG, - ART_PRESSURE_LIMIT_WINDOW_STEP_MMHG ); -} - -/*********************************************************************//** - * @brief - * The isVenousPressureLimitWindowValid function checks whether the - * venous pressure limit window value is within valid range. - * @details \b Inputs: value - * @details \b Outputs: none - * @return TRUE if value is valid, FALSE otherwise - *************************************************************************/ -static BOOL isVenousPressureLimitWindowValid( S32 value ) -{ - return isPressureLimitValueValid( value, - VEN_PRESSURE_LIMIT_WINDOW_MIN_MMHG, - VEN_PRESSURE_LIMIT_WINDOW_MAX_MMHG, - VEN_PRESSURE_LIMIT_WINDOW_STEP_MMHG ); -} - -/*********************************************************************//** - * @brief - * The isVenousAsymmetricPressureLimitWindowValid function checks whether - * the venous asymmetric pressure limit window value is within valid range. - * @details \b Inputs: value - * @details \b Outputs: none - * @return TRUE if value is valid, FALSE otherwise - *************************************************************************/ -static BOOL isVenousAsymmetricPressureLimitWindowValid( S32 value ) -{ - return isPressureLimitValueValid( value, - VEN_ASYM_PRESSURE_LIMIT_WINDOW_MIN_MMHG, - VEN_ASYM_PRESSURE_LIMIT_WINDOW_MAX_MMHG, - VEN_ASYM_PRESSURE_LIMIT_WINDOW_STEP_MMHG ); -} - -/*********************************************************************//** - * @brief - * The isTmpPressureLimitWindowValid function checks whether the TMP - * pressure limit window value is within valid range. - * @details \b Inputs: value - * @details \b Outputs: none - * @return TRUE if value is valid, FALSE otherwise - *************************************************************************/ -static BOOL isTmpPressureLimitWindowValid( S32 value ) -{ - return isPressureLimitValueValid( value, - TMP_PRESSURE_LIMIT_WINDOW_MIN_MMHG, - TMP_PRESSURE_LIMIT_WINDOW_MAX_MMHG, - TMP_PRESSURE_LIMIT_WINDOW_STEP_MMHG ); -} /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Monitors/Pressures.h =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Monitors/Pressures.h (.../Pressures.h) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Monitors/Pressures.h (.../Pressures.h) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -99,8 +99,8 @@ F32 getBaroPressurePSI( void ); BOOL pressureLimitHandleWidenRequest( MESSAGE_T *message ); -BOOL pressureLimitHandleChangeRequest ( MESSAGE_T *message ); + BOOL testPressuresDataPublishIntervalOverride( MESSAGE_T *message ); BOOL testTMPOverride( MESSAGE_T *message ); BOOL testBaroPressureOverride( MESSAGE_T * message ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -110,6 +110,7 @@ { MSG_ID_DD_PRESSURES_DATA, &setDialysatePressure }, { MSG_ID_UI_TREATMENT_PARAMS_TO_VALIDATE, &validateAndSetTreatmentParameters }, { MSG_ID_UI_ULTRAFILTRATION_VOLUME_TO_VALIDATE, &validateAndSetUFVolume }, + { MSG_ID_UI_ULTRAFILTRATION_CHANGE_VALIDATE_REQUEST, &signalUserConfirmationOfUFVolume }, { MSG_ID_UI_TREATMENT_PARAMS_CONFIRMED, &signalUserConfirmationOfTreatmentParameters }, { MSG_ID_UI_DURATION_VALIDATE_REQUEST, &validateAndSetTreatmentDuration }, { MSG_ID_UI_DURATION_CONFIRM_REQUEST, &signalUserConfirmationOfTreatmentDuration }, Index: firmware/App/Services/Messaging.h =================================================================== diff -u -rf0ea13c1a9908920793be07a946dc366d2ab5019 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Services/Messaging.h (.../Messaging.h) (revision f0ea13c1a9908920793be07a946dc366d2ab5019) +++ firmware/App/Services/Messaging.h (.../Messaging.h) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -81,71 +81,6 @@ F32 ufRate; ///< UF rate in mL. } UF_SETTINGS_CONFIRMATION_RESPONSE_PAYLOAD_T; -/// Payload record structure for treatment duration validate request. -typedef struct -{ - U32 duration; ///< Requested treatment duration in minutes. -} DURATION_VALIDATE_REQUEST_PAYLOAD_T; - -/// Payload record structure for treatment duration confirm request. -typedef struct -{ - U32 duration; ///< Confirmed treatment duration in minutes. -} DURATION_CONFIRM_REQUEST_PAYLOAD_T; - -/// Payload record structure for treatment duration change response. -typedef struct -{ - BOOL accepted; ///< Accepted/Rejected - U32 rejectionReason; ///< Rejection reason if not accepted. - U32 duration; ///< Treatment duration in minutes - F32 volume; ///< UF Volume in mL. -} TREATMENT_TIME_CHANGE_RESPONSE_PAYLOAD_T; - -/// Payload record structure for treatment duration validate response. -typedef struct -{ - BOOL accepted; ///< Accepted/Rejected - U32 rejectionReason; ///< Rejection reason if not accepted. - U32 duration; ///< Treatment duration in minutes. - F32 ufVolumeGoal; ///< UF volume goal in mL. - F32 ufRate; ///< UF rate in mL/min. -} DURATION_VALIDATE_RESPONSE_PAYLOAD_T; - -/// Payload record structure for bolus volume change request. -typedef struct -{ - U32 bolusVolume; ///< Requested bolus volume (in mL) -} BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T; - -/// Payload record structure for bolus volume change response. -typedef struct -{ - BOOL accepted; ///< Accepted/Rejected - U32 rejectionReason; ///< Rejection reason if not accepted - U32 bolusVolume; ///< Bolus volume (in mL) -} BOLUS_VOLUME_CHANGE_RESPONSE_PAYLOAD_T; - -/// Payload record structure for pressure limit change request. -typedef struct -{ - S32 arterialPressureLimitWindowMMHG; ///< Arterial pressure limit window in mmHg. - S32 venousPressureLimitWindowMMHG; ///< Venous pressure limit window in mmHg. - S32 venousAsymmetricPressureLimitWindowMMHG; ///< Venous asymmetric pressure limit window in mmHg. - S32 tmpPressureLimitWindowMMHG; ///< TMP pressure limit window in mmHg. -} PRESSURE_LIMIT_CHANGE_REQUEST_T; - -/// Payload record structure for pressure limit change response. -typedef struct -{ - BOOL accepted; ///< Accepted/Rejected - U32 rejectionReason; ///< Rejection reason if not accepted. - S32 arterialPressureLimitWindowMMHG; ///< Arterial pressure limit window in mmHg. - S32 venousPressureLimitWindowMMHG; ///< Venous pressure limit window in mmHg. - S32 venousAsymmetricPressureLimitWindowMMHG; ///< Venous asymmetric pressure limit window in mmHg. - S32 tmpPressureLimitWindowMMHG; ///< TMP pressure limit window in mmHg. -} PRESSURE_LIMIT_CHANGE_RESPONSE_T; - /// Payload record structure for blood / dialysate rate change response. typedef struct { Index: firmware/App/Services/TxParams.c =================================================================== diff -u -r6f02ff4686ec9dfc60247e9ed3fc9c5cc7771543 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Services/TxParams.c (.../TxParams.c) (revision 6f02ff4686ec9dfc60247e9ed3fc9c5cc7771543) +++ firmware/App/Services/TxParams.c (.../TxParams.c) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -146,6 +146,9 @@ 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 validTreatmentDurationReceived = FALSE; ///< Flag indicates valid treatment duration was validated. +static U32 validatedTreatmentDuration_min = 0U; ///< Last validated treatment duration in minutes. +static F32 validatedUFRateLHr = 0.0F; ///< Last validated UF rate in L/hr. // ********** private function prototypes ********** @@ -155,6 +158,12 @@ static void extractTreatmentParamsFromPayload( TREATMENT_PARAMS_DATA_PAYLOAD_T payload ); //static void checkPressureParamsRange( TREATMENT_PARAMS_DATA_PAYLOAD_T* txParams ); static void sendTreatmentParamsResponse( BOOL rejected, U32 *reasons ); +static BOOL isPressureLimitValueValid( S32 value, S32 minValue, S32 maxValue ); +static BOOL isArterialPressureLimitWindowValid( S32 value ); +static BOOL isVenousPressureLimitWindowValid( S32 value ); +static BOOL isVenousAsymmetricPressureLimitWindowValid( S32 value ); +static BOOL isTmpPressureLimitWindowValid( S32 value ); + //static void getInstitutionalRecordEdgeValue( TREATMENT_PARAM_T param, CRITICAL_DATAS_T* value, BOOL isMin ); /*********************************************************************//** @@ -650,6 +659,311 @@ /*********************************************************************//** * @brief + * The validateAndSetTreatmentDuration function handles the UI treatment + * duration validation request during Treatment mode. + * @details \b Message \b Sent: MSG_ID_TD_DURATION_VALIDATE_RESPONSE + * @details \b Inputs: message containing requested treatment duration. + * @details \b Outputs: response updated with acceptance status, rejection + * reason, requested duration, proposed UF volume goal, and + * proposed UF rate. When accepted, validated values are stored + * for use during confirmation. + * @return TRUE if response message is sent successfully, FALSE otherwise. + *************************************************************************/ +BOOL validateAndSetTreatmentDuration( MESSAGE_T *message ) +{ + BOOL result = FALSE; + DURATION_VALIDATE_REQUEST_PAYLOAD_T request; + DURATION_VALIDATE_RESPONSE_PAYLOAD_T response; + F32 presUFVolumeL = 0.0F; + F32 elapsedTreatmentTimeMin = 0.0F; + F32 measuredUFVolumeL = 0.0F; + F32 remainingUFVolumeL = 0.0F; + F32 remainingTreatmentTimeHr = 0.0F; + F32 newUfRateLHr = 0.0F; + F32 newUfRateMlMin = 0.0F; + U32 minDuration = 0U; + U32 maxDuration = 0U; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + response.duration = 0U; + response.ufVolumeGoal = 0.0F; + response.ufRate = 0.0F; + + // Clear previously validated values. + validTreatmentDurationReceived = FALSE; + validatedTreatmentDuration_min = 0U; + validatedUFRateLHr = 0.0F; + + if ( message->hdr.payloadLen == sizeof( request ) ) + { + memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); + + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + response.duration = request.duration; + + presUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + + minDuration = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ); + maxDuration = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_TREATMENT_DURATION ); + + if ( ( request.duration >= minDuration ) && + ( request.duration <= maxDuration ) ) + { + elapsedTreatmentTimeMin = (F32)getActualTreatmentTimeSecs() / (F32)SEC_PER_MIN; + + if ( (F32)request.duration <= elapsedTreatmentTimeMin ) + { + response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; + } + else + { + measuredUFVolumeL = getUltrafiltrationVolumeDrawn(); + remainingUFVolumeL = presUFVolumeL - measuredUFVolumeL; + + if ( remainingUFVolumeL < 0.0F ) + { + remainingUFVolumeL = 0.0F; + } + + remainingTreatmentTimeHr = ( (F32)request.duration - elapsedTreatmentTimeMin ) / (F32)MIN_PER_HOUR; + + if ( remainingTreatmentTimeHr > 0.0F ) + { + newUfRateLHr = remainingUFVolumeL / remainingTreatmentTimeHr; + newUfRateMlMin = newUfRateLHr * (F32)ML_PER_LITER / (F32)MIN_PER_HOUR; + + response.ufVolumeGoal = presUFVolumeL; + response.ufRate = newUfRateLHr; + + if ( newUfRateMlMin <= MAX_UF_RATE_ML_MIN ) + { + response.accepted = TRUE; + + // Store validated values for confirmation. + validTreatmentDurationReceived = TRUE; + validatedTreatmentDuration_min = request.duration; + validatedUFRateLHr = newUfRateLHr; + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_UF_RATE_OUT_OF_RANGE; + } + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; + } + } + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_OUT_OF_RANGE; + } + } + + result = sendMessage( MSG_ID_TD_DURATION_VALIDATE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); + + return result; +} + +/*********************************************************************//** + * @brief + * The validateAndSetBolusVolume function handles the UI fluid bolus + * volume change request during Treatment mode. + * @details \b Message \b Sent: MSG_ID_TD_BOLUS_VOLUME_CHANGE_RESPONSE + * @details \b Inputs: message containing requested bolus volume. + * @details \b Outputs: response updated with acceptance status, + * rejection reason, and bolus volume. + * @return TRUE if response message is sent successfully, FALSE otherwise. + *************************************************************************/ +BOOL validateAndSetBolusVolume( MESSAGE_T *message ) +{ + BOOL result = FALSE; + BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T request; + BOLUS_VOLUME_CHANGE_RESPONSE_PAYLOAD_T response; + U32 minBolusVolume_mL = 0U; + U32 maxBolusVolume_mL = 0U; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + response.bolusVolume = 0U; + + if ( message->hdr.payloadLen == sizeof( BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T ) ) + { + memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); + + response.bolusVolume = request.bolusVolume; + + minBolusVolume_mL = getU32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + maxBolusVolume_mL = getU32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_SALINE_BOLUS_VOLUME ); + + if ( ( request.bolusVolume >= minBolusVolume_mL ) && + ( request.bolusVolume <= maxBolusVolume_mL ) ) + { + response.accepted = TRUE; + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + + setTreatmentParameterU32( TREATMENT_PARAM_SALINE_BOLUS_VOLUME, request.bolusVolume ); + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + } + + result = sendMessage( MSG_ID_TD_BOLUS_VOLUME_CHANGE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); + + return result; +} + +/*********************************************************************//** + * @brief + * The pressureLimitHandleChangeRequest function handles the UI pressure + * limit change request during Treatment mode. + * @details \b Message \b Sent: MSG_ID_TD_PRESSURE_LIMITS_CHANGE_RESPONSE + * @details \b Inputs: message containing requested pressure limit window values. + * @details \b Outputs: response updated with acceptance status, rejection + * reason, and pressure limit window values. When accepted, + * treatment parameters are updated and pressure limits recalculated. + * @return TRUE if response message is sent successfully, FALSE otherwise. + *************************************************************************/ +BOOL pressureLimitHandleChangeRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + BOOL pressureLimitsValid = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + PRESSURE_LIMIT_CHANGE_REQUEST_T request = { 0 }; + PRESSURE_LIMIT_CHANGE_RESPONSE_T response = { 0 }; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + + if ( message->hdr.payloadLen == sizeof( request ) ) + { + memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); + + pressureLimitsValid = isArterialPressureLimitWindowValid( request.arterialPressureLimitWindowMMHG ) && + isVenousPressureLimitWindowValid( request.venousPressureLimitWindowMMHG ) && + isVenousAsymmetricPressureLimitWindowValid( request.venousAsymmetricPressureLimitWindowMMHG ) && + isTmpPressureLimitWindowValid( request.tmpPressureLimitWindowMMHG ); + + if ( TRUE == pressureLimitsValid ) + { + setTreatmentParameterS32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW, + request.arterialPressureLimitWindowMMHG ); + + setTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW, + request.venousPressureLimitWindowMMHG ); + + setTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC, + request.venousAsymmetricPressureLimitWindowMMHG ); + + setTreatmentParameterS32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW, + request.tmpPressureLimitWindowMMHG ); + + updatePressureLimitWindows(); + + result = TRUE; + rejReason = REQUEST_REJECT_REASON_NONE; + } + else + { + rejReason = REQUEST_REJECT_REASON_PARAM_OUT_OF_RANGE; + } + } + + response.accepted = result; + response.rejectionReason = rejReason; + response.arterialPressureLimitWindowMMHG = request.arterialPressureLimitWindowMMHG; + response.venousPressureLimitWindowMMHG = request.venousPressureLimitWindowMMHG; + response.venousAsymmetricPressureLimitWindowMMHG = request.venousAsymmetricPressureLimitWindowMMHG; + response.tmpPressureLimitWindowMMHG = request.tmpPressureLimitWindowMMHG; + + sendMessage( MSG_ID_TD_PRESSURE_LIMITS_CHANGE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); + + return result; +} + +/*********************************************************************//** + * @brief + * The isPressureLimitValueValid function checks whether a pressure limit + * value is within the specified range. + * @details \b Inputs: value, minValue, maxValue. + * @details \b Outputs: none. + * @return TRUE if value is valid, FALSE otherwise. + *************************************************************************/ +static BOOL isPressureLimitValueValid( S32 value, S32 minValue, S32 maxValue ) +{ + return ( ( value >= minValue ) && ( value <= maxValue ) ); +} + +/*********************************************************************//** + * @brief + * Validates the arterial pressure limit window value. + * @details This function checks whether the provided arterial pressure limit window value is within the allowable range defined in treatment parameter limits. + * @param value Arterial pressure limit window value (in mmHg). + * @return TRUE if the value is within valid range, FALSE otherwise. + *************************************************************************/ +static BOOL isArterialPressureLimitWindowValid( S32 value ) +{ + BOOL pressureValid; + + pressureValid = isPressureLimitValueValid( value, getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ), getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ) ); + + return pressureValid; +} + +/*********************************************************************//** + * @brief + * Validates the venous pressure limit window value. + * @details This function checks whether the provided venous pressure limit window value is within the allowable range defined in treatment parameter limits. + * @param value Venous pressure limit window value (in mmHg). + * @return TRUE if the value is within valid range, FALSE otherwise. + *************************************************************************/ +static BOOL isVenousPressureLimitWindowValid( S32 value ) +{ + BOOL pressureValid; + + pressureValid = isPressureLimitValueValid( value, getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ), getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ) ); + + return pressureValid; +} + +/*********************************************************************//** + * @brief + * Validates the venous asymmetric pressure limit window value. + * @details This function checks whether the provided venous asymmetric pressure limit window value is within the allowable range defined in treatment parameter limits. + * @param value Venous asymmetric pressure limit window value (in mmHg). + * @return TRUE if the value is within valid range, FALSE otherwise. + *************************************************************************/ +static BOOL isVenousAsymmetricPressureLimitWindowValid( S32 value ) +{ + BOOL pressureValid; + + pressureValid = isPressureLimitValueValid( value, getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ), getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ) ); + + return pressureValid; +} + +/*********************************************************************//** + * @brief + * Validates the TMP pressure limit window value. + * @details This function checks whether the provided TMP pressure limit window value is within the allowable range defined in treatment parameter limits. + * @param value TMP pressure limit window value (in mmHg). + * @return TRUE if the value is within valid range, FALSE otherwise. + *************************************************************************/ +static BOOL isTmpPressureLimitWindowValid( S32 value ) +{ + BOOL pressureValid; + + pressureValid = isPressureLimitValueValid( value, getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ), getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ) ); + + return pressureValid; +} + +/*********************************************************************//** + * @brief * The resetTreatmentParameters function resets the Treatment Parameters * session flags and parameter values. * @details Inputs: none @@ -733,6 +1047,120 @@ /*********************************************************************//** * @brief + * The signalUserConfirmationOfTreatmentDuration function handles the UI + * treatment duration confirmation request during Treatment mode. + * @details \b Message \b Sent: MSG_ID_TD_DURATION_CONFIRM_RESPONSE + * @details \b Inputs: message containing confirmed treatment duration. + * @details \b Outputs: response updated with acceptance status, rejection + * reason, duration, and UF volume. The confirmed duration is applied + * only when it matches the previously validated duration. + * @return TRUE if response message is sent successfully, FALSE otherwise. + *************************************************************************/ +BOOL signalUserConfirmationOfTreatmentDuration( MESSAGE_T *message ) +{ + BOOL result = FALSE; + DURATION_CONFIRM_REQUEST_PAYLOAD_T request; + DURATION_VALIDATE_RESPONSE_PAYLOAD_T response; + F32 presUFVolumeL = 0.0F; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + response.duration = 0U; + response.ufRate = 0.0F; + + if ( message->hdr.payloadLen == sizeof( request ) ) + { + memcpy( &request, &message->payload[ 0 ], sizeof( request ) ); + + response.duration = request.duration; + response.ufVolumeGoal = presUFVolumeL; + response.ufRate = validatedUFRateLHr; + + if ( ( TRUE == validTreatmentDurationReceived ) && + ( request.duration == validatedTreatmentDuration_min ) ) + { + + setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, validatedTreatmentDuration_min ); + setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFVolumeL , validatedUFRateLHr ); + + response.accepted = TRUE; + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + + // Clear validated values after successful apply. + validTreatmentDurationReceived = FALSE; + validatedTreatmentDuration_min = 0U; + validatedUFRateLHr = 0.0F; + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + } + } + + result = sendMessage( MSG_ID_TD_DURATION_CONFIRM_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08 *)&response, sizeof( response ) ); + + return result; +} + +/*********************************************************************//** + * @brief + * The signalUserConfirmationOfUFVolume function handles the UI + * confirmation request for ultrafiltration (UF) volume change. + * @details \b Message \b Sent: MSG_ID_TD_ULTRAFILTRATION_CHANGE_VALIDATE_RESPONSE + * @details \b Inputs: message containing requested UF volume (mL). + * @details \b Outputs: response updated with acceptance status and + * rejection reason. + * @param message set message from UI which includes the user set + * ultrafiltration volume. + * @return TRUE if response message is sent successfully, FALSE otherwise. + *************************************************************************/ +BOOL signalUserConfirmationOfUFVolume( MESSAGE_T *message ) +{ + BOOL result = FALSE; + UI_RESPONSE_PAYLOAD_T response; + F32 requestedUFVolumeMl = 0.0F; + F32 requestedUFVolumeL = 0.0F; + F32 storedUFVolumeL = 0.0F; + F32 treatmentDurationMin = 0.0F; + F32 newUFRateLHr = 0.0F; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + + if ( sizeof( F32 ) == message->hdr.payloadLen ) + { + memcpy( &requestedUFVolumeMl, message->payload, sizeof( requestedUFVolumeMl ) ); + + requestedUFVolumeL = requestedUFVolumeMl / (F32)ML_PER_LITER; + storedUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + + if ( requestedUFVolumeL == storedUFVolumeL ) + { + treatmentDurationMin = (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + + if ( treatmentDurationMin > 0.0F ) + { + newUFRateLHr = storedUFVolumeL / ( treatmentDurationMin / (F32)MIN_PER_HOUR ); + + setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), storedUFVolumeL, newUFRateLHr ); + + response.accepted = TRUE; + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + } + else + { + response.rejectionReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_MINIMUM; + } + } + } + + result = sendMessage( MSG_ID_TD_ULTRAFILTRATION_CHANGE_VALIDATE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)&response, sizeof( response ) ); + + 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. Index: firmware/App/Services/TxParams.h =================================================================== diff -u -r6f02ff4686ec9dfc60247e9ed3fc9c5cc7771543 -r421336466eff4ba9fef0ca5416043e5d83c63841 --- firmware/App/Services/TxParams.h (.../TxParams.h) (revision 6f02ff4686ec9dfc60247e9ed3fc9c5cc7771543) +++ firmware/App/Services/TxParams.h (.../TxParams.h) (revision 421336466eff4ba9fef0ca5416043e5d83c63841) @@ -80,6 +80,62 @@ U32 maxDialRate; ///< Maximum dialysate flow rate (in mL/min) } TREATMENT_PARAM_RANGE_BROADCAST_PAYLOAD_T; +/// Payload record structure for treatment duration validate request. +typedef struct +{ + U32 duration; ///< Requested treatment duration in minutes. +} DURATION_VALIDATE_REQUEST_PAYLOAD_T; + +/// Payload record structure for treatment duration confirm request. +typedef struct +{ + U32 duration; +} DURATION_CONFIRM_REQUEST_PAYLOAD_T; ///< Confirmed treatment duration in minutes. + +/// Payload record structure for treatment duration validate response. +typedef struct +{ + BOOL accepted; ///< Accepted/Rejected + U32 rejectionReason; ///< Rejection reason if not accepted. + U32 duration; ///< Treatment duration in minutes. + F32 ufVolumeGoal; ///< UF volume goal in mL. + F32 ufRate; ///< UF rate in mL/min. +} DURATION_VALIDATE_RESPONSE_PAYLOAD_T; + +/// Payload record structure for bolus volume change request. +typedef struct +{ + U32 bolusVolume; ///< Requested bolus volume (in mL) +} BOLUS_VOLUME_CHANGE_REQUEST_PAYLOAD_T; + +/// Payload record structure for bolus volume change response. +typedef struct +{ + BOOL accepted; ///< Accepted/Rejected + U32 rejectionReason; ///< Rejection reason if not accepted + U32 bolusVolume; ///< Bolus volume (in mL) +} BOLUS_VOLUME_CHANGE_RESPONSE_PAYLOAD_T; + +/// Payload record structure for pressure limit change request. +typedef struct +{ + S32 arterialPressureLimitWindowMMHG; ///< Arterial pressure limit window in mmHg. + S32 venousPressureLimitWindowMMHG; ///< Venous pressure limit window in mmHg. + S32 venousAsymmetricPressureLimitWindowMMHG; ///< Venous asymmetric pressure limit window in mmHg. + S32 tmpPressureLimitWindowMMHG; ///< TMP pressure limit window in mmHg. +} PRESSURE_LIMIT_CHANGE_REQUEST_T; + +/// Payload record structure for pressure limit change response. +typedef struct +{ + BOOL accepted; ///< Accepted/Rejected + U32 rejectionReason; ///< Rejection reason if not accepted. + S32 arterialPressureLimitWindowMMHG; ///< Arterial pressure limit window in mmHg. + S32 venousPressureLimitWindowMMHG; ///< Venous pressure limit window in mmHg. + S32 venousAsymmetricPressureLimitWindowMMHG; ///< Venous asymmetric pressure limit window in mmHg. + S32 tmpPressureLimitWindowMMHG; ///< TMP pressure limit window in mmHg. +} PRESSURE_LIMIT_CHANGE_RESPONSE_T; + // ********** public function prototypes **************** BOOL setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ); // Set a specified unsigned integer treatment parameter value @@ -93,6 +149,12 @@ BOOL validateAndSetTreatmentParameters( MESSAGE_T *message ); // User provided treatment params to be set and validated BOOL validateAndSetUFVolume( MESSAGE_T *message ); // User provided ultrafiltration volume to be set and validated +BOOL validateAndSetTreatmentDuration( MESSAGE_T *message ); // User provided treatment duration to be set and validated +BOOL validateAndSetBolusVolume( MESSAGE_T *message ); // User provided bolus volume to be set and validated +BOOL pressureLimitHandleChangeRequest( MESSAGE_T *message ); // User provided pressure limit window values to be validated and applied +BOOL signalUserConfirmationOfTreatmentDuration( MESSAGE_T *message ); // Process UI confirm/reject treatment duration +BOOL signalUserConfirmationOfUFVolume( MESSAGE_T *message ); // Process UI confirm/reject ultrafiltration volume change + void resetTreatmentParameters( void ); // Reset all parameters to defaults BOOL signalUserConfirmationOfTreatmentParameters( MESSAGE_T *message ); // Process UI confirm/reject Treatment parameters