Index: firmware/App/Modes/BloodPrime.c =================================================================== diff -u -rc52bfbc3f41fecde11bbec3eb71dc812154fc760 -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision c52bfbc3f41fecde11bbec3eb71dc812154fc760) +++ firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -74,6 +74,8 @@ // ********** private function prototypes ********** static void resetBloodPrimeFlags( void ); +static F32 getBloodPrimeVolume( void ); +static F32 getBloodPrimeSafetyVolume( void ); static BLOOD_PRIME_STATE_T handleBloodPrimeRampState( void ); static void publishBloodPrimeData( void ); Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -rc45ed31616b3b90de1d62d5c4b9db2339228371d -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision c45ed31616b3b90de1d62d5c4b9db2339228371d) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -63,12 +63,12 @@ static U32 rinsebackRate_mL_min; ///< Rinseback rate to use/adjust for this current rinseback only. static U32 rinsebackTimerCtr; ///< Timer counter for time spent in rinseback sub-mode. -static F32 cumulativeRinsebackVolume_mL; ///< Total cumulative rinseback volume (in mL). +static OVERRIDE_F32_T cumulativeRinsebackVolume_mL = { 0.0, 0.0, 0.0, 0 }; ///< Total cumulative rinseback volume (in mL). +static OVERRIDE_F32_T rinsebackVolumeDelivered_Safety = { 0.0, 0.0, 0.0, 0 }; ///< The cumulative independent rinseback volume (in mL) calculated so far. static F32 targetRinsebackVolumePlusAdditional_mL; ///< Target rinseback volume w/ additional volume(s) added (in mL). static F32 additionalRinsebackVolume_mL; ///< Total volume (in mL) delivered so far for additional volume request. static S32 rinsebackMotorCount; ///< The cumulative sum of BP motor encoder counts used for independent rinseback volume check. static U32 rinsebackLastMotorCount; ///< The last BP motor encoder count read for independent rinseback volume check. -static F32 rinsebackVolumeDelivered_Safety; ///< The cumulative independent rinseback volume (in mL) calculated so far. static U32 rinsebackAdditionalTimerCtr; ///< Timer counter for duration of an additional rinseback delivery. static U32 rinsebackPublishTimerCtr; ///< Timer counter for determining interval for rinseback status to be published. @@ -90,6 +90,9 @@ static void setupForRinsebackDelivery( U32 rate ); static void setupForRinsebackStopOrPause( void ); +static F32 getRinsebackVolume( void ); +static F32 getRinsebackSafetyVolume( void ); + static RINSEBACK_STATE_T handleRinsebackStopInitState( void ); static RINSEBACK_STATE_T handleRinsebackRunState( void ); static RINSEBACK_STATE_T handleRinsebackPausedState( void ); @@ -122,11 +125,11 @@ rinsebackRate_mL_min = getTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ); targetRinsebackVolumePlusAdditional_mL = TARGET_RINSEBACK_VOLUME_ML; rinsebackTimerCtr = 0; - cumulativeRinsebackVolume_mL = 0.0; + cumulativeRinsebackVolume_mL.data = 0.0; + rinsebackVolumeDelivered_Safety.data = 0.0; additionalRinsebackVolume_mL = 0.0; rinsebackMotorCount = 0; rinsebackLastMotorCount = getBloodPumpMotorCount(); - rinsebackVolumeDelivered_Safety = 0.0; rinsebackAdditionalTimerCtr = 0; rinsebackPublishTimerCtr = 0; resetRinsebackFlags(); @@ -230,6 +233,46 @@ /*********************************************************************//** * @brief + * The getRinsebackVolume function gets the calculated blood prime volume + * delivered. + * @details Inputs: cumulativeRinsebackVolume_mL + * @details Outputs: none + * @return the current rinseback volume delivered (in mL). + *************************************************************************/ +static F32 getRinsebackVolume( void ) +{ + F32 result = cumulativeRinsebackVolume_mL.data; + + if ( OVERRIDE_KEY == cumulativeRinsebackVolume_mL.override ) + { + result = cumulativeRinsebackVolume_mL.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getRinsebackSafetyVolume function gets the calculated independent + * blood prime volume delivered. + * @details Inputs: rinsebackVolumeDelivered_Safety + * @details Outputs: none + * @return the current rinseback safety volume delivered (in mL). + *************************************************************************/ +static F32 getRinsebackSafetyVolume( void ) +{ + F32 result = rinsebackVolumeDelivered_Safety.data; + + if ( OVERRIDE_KEY == rinsebackVolumeDelivered_Safety.override ) + { + result = rinsebackVolumeDelivered_Safety.ovData; + } + + return result; +} + +/*********************************************************************//** + * @brief * The getCurrentRinsebackState function returns the current state of the * rinseback sub-mode. * @details Inputs: rinsebackState @@ -343,10 +386,10 @@ rinsebackTimerCtr = 0; // Update rinseback volume delivered so far - cumulativeRinsebackVolume_mL += ( getMeasuredBloodFlowRate() * RINSEBACK_FLOW_INTEGRATOR ); + cumulativeRinsebackVolume_mL.data += ( getMeasuredBloodFlowRate() * RINSEBACK_FLOW_INTEGRATOR ); // update independent calculated safety volume delivered so far rinsebackMotorCount = u32BiDiffWithWrap( rinsebackLastMotorCount, getBloodPumpMotorCount() ) / BP_HALL_EDGE_COUNTS_PER_REV; - rinsebackVolumeDelivered_Safety = ( (F32)rinsebackMotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc + rinsebackVolumeDelivered_Safety.data = ( (F32)rinsebackMotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc // Has user requested to end rinseback? if ( TRUE == endRinsebackRequested ) @@ -355,16 +398,16 @@ result = RINSEBACK_STOP_STATE; } // Has rinseback completed? - else if ( cumulativeRinsebackVolume_mL >= TARGET_RINSEBACK_VOLUME_ML ) + else if ( getRinsebackVolume() >= TARGET_RINSEBACK_VOLUME_ML ) { setRinsebackIsCompleted( TRUE ); setupForRinsebackStopOrPause(); result = RINSEBACK_STOP_STATE; #ifndef DISABLE_PUMP_FLOW_CHECKS // Check for under-delivery - if ( rinsebackVolumeDelivered_Safety < MIN_RINSEBACK_SAFETY_VOLUME_ML ) + if ( getRinsebackSafetyVolume() < MIN_RINSEBACK_SAFETY_VOLUME_ML ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE, TARGET_RINSEBACK_VOLUME_ML, rinsebackVolumeDelivered_Safety ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE, TARGET_RINSEBACK_VOLUME_ML, getRinsebackSafetyVolume() ); } #endif } @@ -383,11 +426,11 @@ } #ifndef DISABLE_PUMP_FLOW_CHECKS // Has independent safety volume exceeded safety limit? - else if ( rinsebackVolumeDelivered_Safety > MAX_RINSEBACK_SAFETY_VOLUME_ML ) + else if ( getRinsebackSafetyVolume() > MAX_RINSEBACK_SAFETY_VOLUME_ML ) { setRinsebackIsCompleted( TRUE ); setupForRinsebackStopOrPause(); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE, TARGET_RINSEBACK_VOLUME_ML, rinsebackVolumeDelivered_Safety ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE, TARGET_RINSEBACK_VOLUME_ML, getRinsebackSafetyVolume() ); result = RINSEBACK_STOP_STATE; } #endif @@ -469,7 +512,7 @@ signalRinsebackToRecirc(); } // Has rinseback operation exceeded max time w/o delivering full volume? - if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( cumulativeRinsebackVolume_mL < TARGET_RINSEBACK_VOLUME_ML ) ) + if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < TARGET_RINSEBACK_VOLUME_ML ) ) { signalGoToTreatmentStopped(); activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); @@ -478,8 +521,8 @@ { additionalRinsebackRequested = FALSE; // deliver additional rinseback volume only if max volume not reached and max time not reached - if ( ( ( cumulativeRinsebackVolume_mL + TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) <= MAX_TOTAL_RINSEBACK_VOLUME_ML ) && - ( ( rinsebackTimerCtr < MAX_RINSEBACK_TIME ) || ( cumulativeRinsebackVolume_mL >= TARGET_RINSEBACK_VOLUME_ML ) ) ) + if ( ( ( getRinsebackVolume() + TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) <= MAX_TOTAL_RINSEBACK_VOLUME_ML ) && + ( ( rinsebackTimerCtr < MAX_RINSEBACK_TIME ) || ( getRinsebackVolume() >= TARGET_RINSEBACK_VOLUME_ML ) ) ) { rinsebackAdditionalTimerCtr = 0; additionalRinsebackVolume_mL = 0.0; @@ -518,12 +561,12 @@ // update additional rinseback volume delivered so far additionalRinsebackVolume_mL += rinsebackVolumeSinceLast; - cumulativeRinsebackVolume_mL += rinsebackVolumeSinceLast; + cumulativeRinsebackVolume_mL.data += rinsebackVolumeSinceLast; rinsebackAdditionalTimerCtr++; // Has additional rinseback completed or timed out? if ( ( additionalRinsebackVolume_mL >= TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) || - ( cumulativeRinsebackVolume_mL >= MAX_TOTAL_RINSEBACK_VOLUME_ML ) || + ( getRinsebackVolume() >= MAX_TOTAL_RINSEBACK_VOLUME_ML ) || ( rinsebackAdditionalTimerCtr >= MAX_RINSEBACK_ADDITIONAL_TIME ) ) { setupForRinsebackStopOrPause(); @@ -811,7 +854,7 @@ if ( RINSEBACK_STOP_STATE == rinsebackState ) { - if ( ( cumulativeRinsebackVolume_mL + TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) <= MAX_TOTAL_RINSEBACK_VOLUME_ML ) + if ( ( getRinsebackVolume() + TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML ) <= MAX_TOTAL_RINSEBACK_VOLUME_ML ) { result = TRUE; additionalRinsebackRequested = TRUE; @@ -937,7 +980,7 @@ rinsebackPublishTimerCtr = 0; // If we have completed rinseback, timeout is no longer in force - indicate by zeroing timeout - if ( ( rinsebackState > RINSEBACK_PAUSED_STATE ) && ( cumulativeRinsebackVolume_mL >= TARGET_RINSEBACK_VOLUME_ML ) ) + if ( ( rinsebackState > RINSEBACK_PAUSED_STATE ) && ( getRinsebackVolume() >= TARGET_RINSEBACK_VOLUME_ML ) ) { timeout = 0; } @@ -946,7 +989,8 @@ { data.targetRinsebackVolumeMl = targetRinsebackVolumePlusAdditional_mL; } - data.deliveredRinsebackVolumeMl = cumulativeRinsebackVolume_mL; + data.deliveredRinsebackVolumeMl = getRinsebackVolume(); + data.safetyRinsebackVolumeMl = getRinsebackSafetyVolume(); data.rinsebackFlowRateMlMin = rinsebackRate_mL_min; if ( RINSEBACK_RUN_ADDITIONAL_STATE == rinsebackState ) { @@ -958,4 +1002,100 @@ } } + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetRinsebackVolumeOverride function overrides the calculated + * rinseback volume delivered. + * @details Inputs: none + * @details Outputs: cumulativeRinsebackVolume_mL + * @param vol override calculated rinseback volume (in mL) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetRinsebackVolumeOverride( F32 vol ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + cumulativeRinsebackVolume_mL.ovData = vol; + cumulativeRinsebackVolume_mL.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetRinsebackVolumeOverride function resets the override of the + * calculated rinseback volume. + * @details Inputs: none + * @details Outputs: cumulativeRinsebackVolume_mL + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetRinsebackVolumeOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + cumulativeRinsebackVolume_mL.override = OVERRIDE_RESET; + cumulativeRinsebackVolume_mL.ovData = cumulativeRinsebackVolume_mL.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetRinsebackSafetyVolumeOverride function overrides the calculated + * rinseback volume. + * @details Inputs: none + * @details Outputs: rinsebackVolumeDelivered_Safety + * @param vol override calculated rinseback safety volume (in mL) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetRinsebackSafetyVolumeOverride( F32 vol ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rinsebackVolumeDelivered_Safety.ovData = vol; + rinsebackVolumeDelivered_Safety.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetRinsebackSafetyVolumeOverride function resets the override of the + * calculated rinseback safety volume. + * @details Inputs: none + * @details Outputs: rinsebackVolumeDelivered_Safety + * @return TRUE if reset successful, FALSE if not + *************************************************************************/ +BOOL testResetRinsebackSafetyVolumeOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + rinsebackVolumeDelivered_Safety.override = OVERRIDE_RESET; + rinsebackVolumeDelivered_Safety.ovData = rinsebackVolumeDelivered_Safety.ovInitData; + } + + return result; +} + /**@}*/ Index: firmware/App/Modes/Rinseback.h =================================================================== diff -u -r89f4c7f0995e2094b3f26fc7e7e12371e847abac -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Modes/Rinseback.h (.../Rinseback.h) (revision 89f4c7f0995e2094b3f26fc7e7e12371e847abac) +++ firmware/App/Modes/Rinseback.h (.../Rinseback.h) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -44,6 +44,7 @@ U32 rinsebackFlowRateMlMin; U32 timeout; U32 countdown; + F32 safetyRinsebackVolumeMl; } RINSEBACK_DATA_PAYLOAD_T; #pragma pack(pop) @@ -57,6 +58,11 @@ void signalRinsebackUserAction( REQUESTED_RINSEBACK_USER_ACTIONS_T action ); // from user RINSEBACK_STATE_T getCurrentRinsebackState( void ); +BOOL testSetRinsebackVolumeOverride( F32 vol ); +BOOL testResetRinsebackVolumeOverride( void ); +BOOL testSetRinsebackSafetyVolumeOverride( F32 vol ); +BOOL testResetRinsebackSafetyVolumeOverride( void ); + /**@}*/ #endif Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r2b2d7945bca8305ecd7f9577ad7d8457089282f2 -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 2b2d7945bca8305ecd7f9577ad7d8457089282f2) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -1559,6 +1559,14 @@ handleBloodPrimeSafetyVolumeOverrideRequest( message ); break; + case MSG_ID_HD_RINSEBACK_VOLUME_OVERRIDE: + handleRinsebackVolumeOverrideRequest( message ); + break; + + case MSG_ID_HD_RINSEBACK_SAFETY_VOLUME_OVERRIDE: + handleRinsebackSafetyVolumeOverrideRequest( message ); + break; + case MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE: handleTestSyringePumpDataBroadcastIntervalOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r40b37059da0ecd27dc9beb48614f6f3869d18732 -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 40b37059da0ecd27dc9beb48614f6f3869d18732) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -5612,6 +5612,70 @@ /*********************************************************************//** * @brief + * The handleRinsebackVolumeOverrideRequest function handles a request to + * override the calculated rinseback volume (in mL). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleRinsebackVolumeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetRinsebackVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetRinsebackVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleRinsebackSafetyVolumeOverrideRequest function handles a request to + * override the calculated safety rinseback volume (in mL). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleRinsebackSafetyVolumeOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) + { + result = testSetRinsebackSafetyVolumeOverride( payload.state.f32 ); + } + else + { + result = testResetRinsebackSafetyVolumeOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleHDSoftwareResetRequest function handles a request to reset the * HD firmware processor. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rbcbdc9a68b54b75f93be66dd5c2ee6a5733565cd -ra2a882ee989ef142887cd54a0f8311addaca812d --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision bcbdc9a68b54b75f93be66dd5c2ee6a5733565cd) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a2a882ee989ef142887cd54a0f8311addaca812d) @@ -639,6 +639,12 @@ // MSG_ID_HD_BLOOD_PRIME_SAFETY_VOLUME_OVERRIDE void handleBloodPrimeSafetyVolumeOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_RINSEBACK_VOLUME_OVERRIDE +void handleRinsebackVolumeOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_HD_RINSEBACK_SAFETY_VOLUME_OVERRIDE +void handleRinsebackSafetyVolumeOverrideRequest( MESSAGE_T *message ); + // MSG_ID_SUPER_CLEAR_ALARMS_CMD void handleTestSuperClearAlarmsRequest( MESSAGE_T *message );