Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rc9890bc0bc9a1d779be9fec7e0478cfc6fba1cfb -rbdbb0ede1af201d43125d663a4ca5740e39509f6 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision c9890bc0bc9a1d779be9fec7e0478cfc6fba1cfb) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision bdbb0ede1af201d43125d663a4ca5740e39509f6) @@ -76,6 +76,14 @@ /// Macro to calculate the remaining treatment time in seconds. #define CALC_TREAT_TIME_REMAINING_IN_SECS() ( (S32)presTreatmentTimeSecs - (S32)( treatmentTimeMS / MS_PER_SECOND ) ) +/// Treatment duration requested values +typedef struct +{ + U32 requestedTxDurationMins; ///< Requested treatment duration from the user in minutes. + F32 newUFRateMLPM; ///< New calculated UF rate in mL/Min. + BOOL isUFRateConfInProgress; ///< Boolean flag to indicate whether a new UF rate confirmation has been requested. +} TREATMENT_DURATION_RQST_T; + // ********** private data ********** static TREATMENT_STATE_T currentTreatmentState; ///< Current state (sub-mode) of treatment mode. @@ -134,6 +142,8 @@ static U32 treatmentStartTimeStamp; ///< Treatment start timestampt for logging purpose. static U32 treatmentEndTimeStamp; ///< Treatment end timestampt for logging purpose. +static TREATMENT_DURATION_RQST_T txDurationRequest; ///< Treatment duration request structure. + // ********** private function prototypes ********** static void broadcastTreatmentSettingsRanges( void ); @@ -148,6 +158,7 @@ static TREATMENT_STATE_T handleTreatmentEndState( void ); static void resetSignalFlags( void ); static void resetAlarmSignalFlags( void ); +static void checkUFRateConfirmationMessageFromUI( void ); /*********************************************************************//** * @brief @@ -200,6 +211,10 @@ treatmentStartTimeStamp = getRTCTimestamp(); treatmentEndTimeStamp = 0; + txDurationRequest.requestedTxDurationMins = 0; + txDurationRequest.newUFRateMLPM = 0.0F; + txDurationRequest.isUFRateConfInProgress = FALSE; + // reset dialysate temperature alarm persistences prior to starting a treatment. resetPersistentAlarmTimer( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_SAFETY_TEMP ); resetPersistentAlarmTimer( ALARM_ID_HD_DIALYSATE_TEMP_ABOVE_TARGET_TEMP ); @@ -790,6 +805,8 @@ U32 msSinceLast = calcTimeBetween( lastTreatmentTimeStamp, newTime ); DIALYSIS_STATE_T dialysisState = getDialysisState(); + checkUFRateConfirmationMessageFromUI(); + // Update treatment time (unless delivering a saline bolus or is in blood leak zeroing state other than flush reservoir to DPi state) switch ( dialysisState ) { @@ -1075,14 +1092,23 @@ if ( ( TRUE == isTxTimeValid ) && ( dialVolume <= MAX_DIALYSATE_VOLUME_ML ) && ( TRUE == isUFRateValid ) ) { + GENERIC_CONFIRMATION_REQUEST_T genericConfRequest; + result = TRUE; - sendTreatmentLogEventData( TREATMENT_DURATION_CHANGE_EVENT, ( presTreatmentTimeSecs / SEC_PER_MIN ), treatmentTime ); - presTreatmentTimeSecs = treatmentTime * SEC_PER_MIN; - presUFRate = newUFRateMLPM; - setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); - setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, ( presTreatmentTimeSecs / SEC_PER_MIN ) ); - setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); - signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + + txDurationRequest.requestedTxDurationMins = treatmentTime; + txDurationRequest.newUFRateMLPM = newUFRateMLPM; + txDurationRequest.isUFRateConfInProgress = TRUE; + + genericConfRequest.requestID = GENERIC_CONFIRM_ID_UF_RATE_CHANGE_IN_TX_DURATION_CHANGE; + genericConfRequest.requestType = GENERIC_CONFIRM_CMD_REQUEST_OPEN; + genericConfRequest.rejectReason = 0; + genericConfRequest.genericPayload1 = txDurationRequest.newUFRateMLPM; + genericConfRequest.genericPayload2 = 0.0F; + genericConfRequest.genericPayload3 = 0.0F; + genericConfRequest.genericPayload4 = 0.0F; + + sendConfirmationRequest( &genericConfRequest ); } else { @@ -1106,8 +1132,7 @@ { rejectReason = REQUEST_REJECT_REASON_NOT_IN_TREATMENT_MODE; } - else if ( ( currentTreatmentState <= TREATMENT_START_STATE ) || - ( currentTreatmentState >= TREATMENT_END_STATE ) ) + else if ( ( currentTreatmentState <= TREATMENT_START_STATE ) || ( currentTreatmentState >= TREATMENT_END_STATE ) ) { rejectReason = REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE; } @@ -1120,8 +1145,13 @@ rejectReason = REQUEST_REJECT_REASON_TREATMENT_TIME_LESS_THAN_CURRENT; } } - // Send response to request - sendChangeTreatmentDurationResponse( result, rejectReason, presTreatmentTimeSecs / SEC_PER_MIN, presMaxUFVolumeML ); + + if ( rejectReason != REQUEST_REJECT_REASON_NONE ) + { + // Send response to request only if there is a rejection + sendChangeTreatmentDurationResponse( result, rejectReason, presTreatmentTimeSecs / SEC_PER_MIN, presMaxUFVolumeML ); + } + // Send new ranges for settings treatmentParamsRangesBroadcastTimerCtr = getU32OverrideValue( &treatmentParamRangesPublishInterval ); broadcastTreatmentSettingsRanges(); @@ -1679,6 +1709,53 @@ endTreatmentAlarmResponseRequest = FALSE; } +/*********************************************************************//** + * @brief + * The checkUFRateConfirmationMessageFromUI function checks whether a response + * from UI has been received to see if the new UF rate due to change of + * the treatment duration is accepted or rejected. + * @details Inputs: txDurationRequest + * @details Outputs: presTreatmentTimeSecs, presUFRate, txDurationRequest, + * presMaxUFVolumeML + * @return none + *************************************************************************/ +static void checkUFRateConfirmationMessageFromUI( void ) +{ + if ( TRUE == txDurationRequest.isUFRateConfInProgress ) + { + BOOL result = FALSE; + CONFIRMATION_REQUEST_STATUS_T status = getConfirmationRequestStatus( GENERIC_CONFIRM_ID_UF_RATE_CHANGE_IN_TX_DURATION_CHANGE ); + + if ( ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == status ) || ( CONFIRMATION_REQUEST_STATUS_REJECTED == status ) ) + { + if ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == status ) + { + result = TRUE; + sendTreatmentLogEventData( TREATMENT_DURATION_CHANGE_EVENT, ( presTreatmentTimeSecs / SEC_PER_MIN ), txDurationRequest.requestedTxDurationMins ); + presTreatmentTimeSecs = txDurationRequest.requestedTxDurationMins * SEC_PER_MIN; + presUFRate = txDurationRequest.newUFRateMLPM; + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); + setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, ( presTreatmentTimeSecs / SEC_PER_MIN ) ); + setDialysisDialInFlowAndUFRate( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); + signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + } + + // Regardless of accept or reject there is no reject reason. + sendChangeTreatmentDurationResponse( result, 0, ( presTreatmentTimeSecs / SEC_PER_MIN ), presMaxUFVolumeML ); + // Send new ranges for settings + treatmentParamsRangesBroadcastTimerCtr = getU32OverrideValue( &treatmentParamRangesPublishInterval ); + broadcastTreatmentSettingsRanges(); + // Send time/state data immediately for UI update + broadcastTreatmentTimeAndState(); + + // Done with treatment duration changes whether they were accepted or rejected. + txDurationRequest.isUFRateConfInProgress = FALSE; + txDurationRequest.newUFRateMLPM = 0.0F; + txDurationRequest.requestedTxDurationMins = 0; + } + } +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -rfba69244d94307e50fefaa1e88bcbb979584461e -rbdbb0ede1af201d43125d663a4ca5740e39509f6 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision fba69244d94307e50fefaa1e88bcbb979584461e) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision bdbb0ede1af201d43125d663a4ca5740e39509f6) @@ -451,7 +451,14 @@ U32 pendingIndex = 0; CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_PENDING; U32 i; + GENERIC_CONFIRMATION_REQUEST_T genConfRqst; + genConfRqst.rejectReason = 0; + genConfRqst.genericPayload1 = 0.0F; + genConfRqst.genericPayload2 = 0.0F; + genConfRqst.genericPayload3 = 0.0F; + genConfRqst.genericPayload4 = 0.0F; + for ( i = 0; i < MAX_PENDING_CONFIRM_REQUESTS; i++ ) { if ( confirmRequests[ i ].requestID == requestID ) @@ -462,18 +469,24 @@ // Send UI clear if ( CONFIRMATION_REQUEST_STATUS_TIMEOUT == status ) { - sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE, 0 ); + genConfRqst.requestID = confirmRequests[ i ].requestID; + genConfRqst.requestType = GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE; + + sendConfirmationRequest( &genConfRqst ); } else { - sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_ACCEPT_CLOSE, 0 ); + genConfRqst.requestID = confirmRequests[ i ].requestID; + genConfRqst.requestType = GENERIC_CONFIRM_CMD_ACCEPT_CLOSE; + + sendConfirmationRequest( &genConfRqst ); } // Clear the confirmation request, it is done and consumed - confirmRequests[ i ].requestID = GENERIC_CONFIRM_ID_NONE; + confirmRequests[ i ].requestID = GENERIC_CONFIRM_ID_NONE; confirmRequests[ i ].requestType = GENERIC_CONFIRM_CMD_REQUEST_OPEN; - confirmRequests[ i ].timeStamp = 0; - confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_UNUSED; + confirmRequests[ i ].timeStamp = 0; + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_UNUSED; } } else if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) @@ -496,8 +509,11 @@ if ( ( CONFIRMATION_REQUEST_STATUS_PENDING != status ) && ( TRUE == pending ) ) { + genConfRqst.requestID = confirmRequests[ i ].requestID; + genConfRqst.requestType = confirmRequests[ pendingIndex ].requestType; + // Last confirmation cleared, pending request must be resent to UI - sendConfirmationRequest( confirmRequests[ pendingIndex ].requestID, confirmRequests[ pendingIndex ].requestType, 0 ); + sendConfirmationRequest( &genConfRqst ); } return status; @@ -556,17 +572,30 @@ // If not already pending, add confirmation to list of pending confirmations and send to UI to be displayed if ( confirmAlreadyPending != TRUE ) { + GENERIC_CONFIRMATION_REQUEST_T genConfRqst; + + genConfRqst.rejectReason = rejectReason; + genConfRqst.genericPayload1 = 0.0F; + genConfRqst.genericPayload2 = 0.0F; + genConfRqst.genericPayload3 = 0.0F; + genConfRqst.genericPayload4 = 0.0F; + for ( i = 0; i < MAX_PENDING_CONFIRM_REQUESTS; i++ ) { if ( CONFIRMATION_REQUEST_STATUS_UNUSED == confirmRequests[ i ].status ) { // Save the confirmation request info - confirmRequests[ i ].requestID = requestID; + confirmRequests[ i ].requestID = requestID; confirmRequests[ i ].requestType = requestType; - confirmRequests[ i ].timeStamp = getMSTimerCount(); - confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_PENDING; - newID = requestID; - sendConfirmationRequest( requestID, requestType, rejectReason ); + confirmRequests[ i ].timeStamp = getMSTimerCount(); + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_PENDING; + newID = requestID; + + // Get ready for the generic confirmation request + genConfRqst.requestID = requestID; + genConfRqst.requestType = requestType; + + sendConfirmationRequest( &genConfRqst ); break; } } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rc9890bc0bc9a1d779be9fec7e0478cfc6fba1cfb -rbdbb0ede1af201d43125d663a4ca5740e39509f6 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c9890bc0bc9a1d779be9fec7e0478cfc6fba1cfb) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision bdbb0ede1af201d43125d663a4ca5740e39509f6) @@ -3504,29 +3504,21 @@ * The sendConfirmationRequest function sends a confirmation request to UI * @details Inputs: none * @details Outputs: none - * @param requestID ID of confirmation being requested - * @param requestType Type of confirmation being requested - * @param rejectReason Reason Reason for reject if type is reject + * @param request ID pointer to generic message request structure * @return none *************************************************************************/ -void sendConfirmationRequest( GENERIC_CONFIRM_ID_T requestID, GENERIC_CONFIRM_COMMAND_T requestType, U32 rejectReason ) +void sendConfirmationRequest( GENERIC_CONFIRMATION_REQUEST_T *request ) { MESSAGE_T msg; U08 *payloadPtr = msg.payload; - U32 temp_request = requestID; // Create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_HD_UI_CONFIRMATION_REQUEST; // The payload length is U32 Request ID, U32 Type, U32 Reject Reason - msg.hdr.payloadLen = 3 * sizeof( U32 ); + msg.hdr.payloadLen = sizeof( GENERIC_CONFIRMATION_REQUEST_T ); - memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - temp_request = requestType; - memcpy( payloadPtr, &temp_request, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &rejectReason, sizeof( U32 ) ); + memcpy( payloadPtr, request, sizeof( GENERIC_CONFIRMATION_REQUEST_T ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rfba69244d94307e50fefaa1e88bcbb979584461e -rbdbb0ede1af201d43125d663a4ca5740e39509f6 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision fba69244d94307e50fefaa1e88bcbb979584461e) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision bdbb0ede1af201d43125d663a4ca5740e39509f6) @@ -136,6 +136,18 @@ U32 minDialRate; ///< Minimum dialysate flow rate (in mL/min) U32 maxDialRate; ///< Maximum dialysate flow rate (in mL/min) } TREATMENT_PARAM_BROADCAST_PAYLOAD_T; + +/// Payload structure for generic confirmation request +typedef struct +{ + GENERIC_CONFIRM_ID_T requestID; ///< Generic request ID. + GENERIC_CONFIRM_COMMAND_T requestType; ///< Generic request type. + U32 rejectReason; ///< Reject reason. + F32 genericPayload1; ///< Generic payload 1. + F32 genericPayload2; ///< Generic payload 2. + F32 genericPayload3; ///< Generic payload 3. + F32 genericPayload4; ///< Generic payload 4. +} GENERIC_CONFIRMATION_REQUEST_T; // ********** public function prototypes ********** @@ -523,7 +535,7 @@ void handleUIConfirmationResponse( MESSAGE_T *message ); // MSG_ID_HD_REQUEST_UI_CONFIRMATION -void sendConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ); +void sendConfirmationRequest( GENERIC_CONFIRMATION_REQUEST_T *request ); // MSG_ID_HD_REQUEST_DG_ALARMS BOOL sendRequestForDGResendAlarms( void );