Index: firmware/App/Modes/BloodPrime.c =================================================================== diff -u --- firmware/App/Modes/BloodPrime.c (revision 0) +++ firmware/App/Modes/BloodPrime.c (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -0,0 +1,280 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 TreatmentEnd.c +* +* @author (last) Sean Nash +* @date (last) 04-Feb-2021 +* +* @author (original) Sean +* @date (original) 04-Feb-2021 +* +***************************************************************************/ + +#include "AirTrap.h" +#include "BloodFlow.h" +#include "BloodPrime.h" +#include "DialInFlow.h" +#include "DialOutFlow.h" +#include "ModeTreatment.h" +#include "ModeTreatmentParams.h" +#include "OperationModes.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" +#include "Utilities.h" +#include "Valves.h" + +/** + * @addtogroup BloodPrime + * @{ + */ + +// ********** private definitiions *********** + +#define TARGET_BLOOD_PRIME_VOLUME_ML 300.0 ///< Target blood prime volume to prime the blood side circuit (in mL). TODO - get from Systems when available +#define MIN_RAMP_TIME_SEC 60 ///< Minimum ramp time for blood prime (in seconds). +/// Maximum blood prime volume measured by independent means (as % of target). +static const F32 MAX_BLOOD_PRIME_SAFETY_VOLUME_ML = ( TARGET_BLOOD_PRIME_VOLUME_ML * 1.2 ); +/// Minimum blood prime volume measured by independent means (as % of target). +static const F32 MIN_BLOOD_PRIME_SAFETY_VOLUME_ML = ( TARGET_BLOOD_PRIME_VOLUME_ML * 0.8 ); + +/// Initial flow rate for blood pump when starting blood prime operation. +#define BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN 100 + +/// Interval at which blood prime ramping is controlled. +#define BLOOD_PRIME_RAMPING_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + +/// Interval at which blood prime progress is to be published to UI. +#define BLOOD_PRIME_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + +/// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. +static const F32 BLOOD_PRIME_FLOW_INTEGRATOR = 1.0 / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + +// ********** private data ********** + +static BLOOD_PRIME_STATE_T bloodPrimeState; ///< Current state of the blood prime sub-mode. + +static F32 bloodPrimeRampFlowRate_mL_min; ///< Current blood pump ramp flow rate. +static F32 bloodPrimeRampStep_mL; ///< Blood pump volume step size for ramping. + +static U32 bloodPrimeRampControlTimerCtr; ///< Timer counter for determining interval for controlling BP ramp. +static U32 bloodPrimePublishTimerCtr; ///< Timer counter for determining interval for blood prime status to be published. + +static F32 cumulativeBloodPrimeVolume_mL; ///< Total cumulative blood prime volume (in mL). +static U32 bloodPrimeMotorCount; ///< The cumulative sum of BP motor encoder counts used for independent blood prime volume check. +static U32 bloodPrimeLastMotorCount; ///< The last BP motor encoder count read for independent blood prime volume check. +static F32 bloodPrimeVolumeDelivered_Safety; ///< The cumulative independent blood prime volume (in mL) calculated so far. + +// ********** private function prototypes ********** + +static void resetBloodPrimeFlags( void ); + +static BLOOD_PRIME_STATE_T handleBloodPrimeRampState( void ); + +static void publishBloodPrimeData( void ); + +/*********************************************************************//** + * @brief + * The initBloodPrime function initializes the Blood Prime sub-mode + * module. + * @details Inputs: none + * @details Outputs: Blood prime sub-mode module initialized. + * @return none + *************************************************************************/ +void initBloodPrime( void ) +{ + U32 setBPRate = getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ); + + bloodPrimeState = BLOOD_PRIME_RAMP_STATE; + bloodPrimeRampControlTimerCtr = 0; + bloodPrimePublishTimerCtr = 0; + cumulativeBloodPrimeVolume_mL = 0.0; + bloodPrimeMotorCount = 0; + bloodPrimeLastMotorCount = 0; + bloodPrimeVolumeDelivered_Safety = 0.0; + resetBloodPrimeFlags(); + + bloodPrimeRampFlowRate_mL_min = (F32)BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN; + // Calculate BP ramp step size + if ( setBPRate <= BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN ) + { + bloodPrimeRampStep_mL = 0.0; + } + else + { + F32 rampRateSpan = (F32)( setBPRate - BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN ); + F32 estRampSeconds = ( ( TARGET_BLOOD_PRIME_VOLUME_ML / (F32)setBPRate + TARGET_BLOOD_PRIME_VOLUME_ML / (F32)BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN ) / 2.0 ) * (F32)SEC_PER_MIN; + + if ( estRampSeconds < (F32)MIN_RAMP_TIME_SEC ) + { + estRampSeconds = (F32)MIN_RAMP_TIME_SEC; + } + bloodPrimeRampStep_mL = rampRateSpan / estRampSeconds; + } +} + +/*********************************************************************//** + * @brief + * The resetBloodPrimeFlags function resets the blood prime request flags. + * @details Inputs: none + * @details Outputs: Blood prime request flags reset to FALSE. + * @return none + *************************************************************************/ +static void resetBloodPrimeFlags( void ) +{ + // No flags for now +} + +/*********************************************************************//** + * @brief + * The transitionToBloodPrime function prepares for transition to blood prime + * sub-mode. + * @details Inputs: none + * @details Outputs: actuators set for initial state of blood prime sub-mode + * @return none + *************************************************************************/ +void transitionToBloodPrime( void ) +{ + // Set valves + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBA, VALVE_POSITION_B_OPEN ); + setValvePosition( VBV, VALVE_POSITION_B_OPEN ); + + // Ensure dialysate outlet and Heparin pumps are stopped + signalDialOutPumpHardStop(); + // TODO - stop Heparin pump + // start blood and dialysate inlet pumps + setBloodPumpTargetFlowRate( BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_RECIRC, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + cmdStartDGTrimmerHeater(); + + // Start air trap control + startAirTrapControl(); + + // Set user alarm recovery actions allowed in this sub-mode + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); +} + +/*********************************************************************//** + * @brief + * The execBloodPrime function executes the Blood Prime sub-mode state machine. + * @details Inputs: bloodPrimeState + * @details Outputs: bloodPrimeState + * @return none + *************************************************************************/ +void execBloodPrime( void ) +{ + switch ( bloodPrimeState ) + { + case BLOOD_PRIME_RAMP_STATE: + bloodPrimeState = handleBloodPrimeRampState(); + break; + + default: + // TODO - s/w fault + break; + } + + // Blood prime flags should be handled by now - reset in case not handled by current state + resetBloodPrimeFlags(); + + // Publish blood prime progress while in blood prime sub-mode + publishBloodPrimeData(); +} + +/*********************************************************************//** + * @brief + * The handleBloodPrimeRampState function handles the blood prime ramp + * state operations. + * @details Inputs: flags + * @details Outputs: flags handled + * @return next blood prime end ramp state + *************************************************************************/ +static BLOOD_PRIME_STATE_T handleBloodPrimeRampState( void ) +{ + BLOOD_PRIME_STATE_T result = BLOOD_PRIME_RAMP_STATE; + U32 bldPumpMotorCount = getBloodPumpMotorCount(); + U32 bldPumpMotorDelta = u32DiffWithWrap( bloodPrimeLastMotorCount, bldPumpMotorCount ); + + // update blood prime volume delivered so far + cumulativeBloodPrimeVolume_mL += ( getMeasuredBloodFlowRate() * BLOOD_PRIME_FLOW_INTEGRATOR ); + // update independent calculated safety volume delivered so far + bloodPrimeMotorCount += bldPumpMotorDelta; + bloodPrimeLastMotorCount = bldPumpMotorCount; + bloodPrimeVolumeDelivered_Safety = ( (F32)bloodPrimeMotorCount * VOLUME_PER_BP_MOTOR_REV_ML ); // TODO - include upstream pressure compensation to this calc + + // Has blood prime completed? + if ( cumulativeBloodPrimeVolume_mL >= TARGET_BLOOD_PRIME_VOLUME_ML ) + { + // check for under-delivery + if ( bloodPrimeVolumeDelivered_Safety < MIN_BLOOD_PRIME_SAFETY_VOLUME_ML ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PRIME_VOLUME_CHECK_FAILURE, TARGET_BLOOD_PRIME_VOLUME_ML, bloodPrimeVolumeDelivered_Safety ); + } + else + { + setBloodIsPrimed( TRUE ); + signalBloodPrimeToDialysis(); + } + } + // Has independent safety volume exceeded safety limit? + else if ( bloodPrimeVolumeDelivered_Safety > MAX_BLOOD_PRIME_SAFETY_VOLUME_ML ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PRIME_VOLUME_CHECK_FAILURE, TARGET_BLOOD_PRIME_VOLUME_ML, bloodPrimeVolumeDelivered_Safety ); + } + else + { + // ramp blood pump on ramp interval + if ( ++bloodPrimeRampControlTimerCtr >= BLOOD_PRIME_RAMPING_INTERVAL ) + { + bloodPrimeRampControlTimerCtr = 0; + bloodPrimeRampFlowRate_mL_min += bloodPrimeRampStep_mL; + setBloodPumpTargetFlowRate( (U32)bloodPrimeRampFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getCurrentBloodPrimeState function returns the current state of the + * blood prime sub-mode. + * @details Inputs: bloodPrimeState + * @details Outputs: none + * @return bloodPrimeState + *************************************************************************/ +TREATMENT_END_STATE_T getCurrentBloodPrimeState( void ) +{ + return bloodPrimeState; +} + +/*********************************************************************//** + * @brief + * The publishBloodPrimeData function publishes blood prime progress to UI + * at 1 Hz interval. + * @details Inputs: bloodPrimePublishTimerCtr + * @details Outputs: rinseback data published + * @return none + *************************************************************************/ +static void publishBloodPrimeData( void ) +{ + if ( ++bloodPrimePublishTimerCtr >= BLOOD_PRIME_DATA_PUBLISH_INTERVAL ) + { + BLOOD_PRIME_DATA_PAYLOAD_T data; + + bloodPrimePublishTimerCtr = 0; + data.targetBloodPrimeVolumeMl = TARGET_BLOOD_PRIME_VOLUME_ML; + data.deliveredBloodPrimeVolumeMl = cumulativeBloodPrimeVolume_mL; + broadcastBloodPrimeData( data ); + } +} + +/**@}*/ Index: firmware/App/Modes/BloodPrime.h =================================================================== diff -u --- firmware/App/Modes/BloodPrime.h (revision 0) +++ firmware/App/Modes/BloodPrime.h (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -0,0 +1,60 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 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 BloodPrime.h +* +* @author (last) Sean Nash +* @date (last) 06-Feb-2021 +* +* @author (original) Sean +* @date (original) 06-Feb-2021 +* +***************************************************************************/ + +#ifndef __BLOOD_PRIME_H__ +#define __BLOOD_PRIME_H__ + +#include "HDCommon.h" +#include "HDDefs.h" + +/** + * @defgroup BloodPrime BloodPrime + * @brief Blood prime sub-mode of treatment mode. + * The blood prime state is where we go when treatment is first started or + * when returning to treatment after a rinseback. + * In this state, there is no Heparin delivery nor ultrafiltration. + * In this state, treatment timer is not running. No dialysis. Dialyzer is bypassed. + * In this state, blood pump is slowly ramped to set rate until the prime volume is delivered. + * + * @addtogroup BloodPrime + * @{ + */ + +// ********** public definitions ****************** + +#pragma pack(push,1) + +/// Payload record structure for a blood prime data broadcast message. +typedef struct +{ + F32 targetBloodPrimeVolumeMl; + F32 deliveredBloodPrimeVolumeMl; +} BLOOD_PRIME_DATA_PAYLOAD_T; + +#pragma pack(pop) + +// ********** public function prototypes ********** + +void initBloodPrime( void ); +void transitionToBloodPrime( void ); +void execBloodPrime( void ); + +TREATMENT_END_STATE_T getCurrentBloodPrimeState( void ); + +/**@}*/ + +#endif Index: firmware/App/Modes/ModeFault.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModeFault.h (.../ModeFault.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Modes/ModeFault.h (.../ModeFault.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -29,7 +29,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initFaultMode( void ); // Initialize this module void transitionToFaultMode( void ); // Prepares for transition to fault mode Index: firmware/App/Modes/ModeInitPOST.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModeInitPOST.h (.../ModeInitPOST.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Modes/ModeInitPOST.h (.../ModeInitPOST.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -29,7 +29,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initInitAndPOSTMode( void ); // Initialize this module void transitionToInitAndPOSTMode( void ); // Prepares for transition to init. & POST mode Index: firmware/App/Modes/ModePostTreat.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModePostTreat.h (.../ModePostTreat.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Modes/ModePostTreat.h (.../ModePostTreat.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -29,7 +29,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initPostTreatmentMode( void ); // Initialize this module void transitionToPostTreatmentMode( void ); // Prepares for transition to post-treatment mode Index: firmware/App/Modes/ModePreTreat.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Modes/ModePreTreat.h (.../ModePreTreat.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -29,7 +29,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initPreTreatmentMode( void ); // Initialize this module void transitionToPreTreatmentMode( void ); // Prepares for transition to pre-treatment mode Index: firmware/App/Modes/ModeService.h =================================================================== diff -u -r30f049651877229042e3f8700c8596e5b9a1e0f4 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModeService.h (.../ModeService.h) (revision 30f049651877229042e3f8700c8596e5b9a1e0f4) +++ firmware/App/Modes/ModeService.h (.../ModeService.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -29,7 +29,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initServiceMode( void ); // Initialize this module void transitionToServiceMode( void ); // Prepares for transition to service mode Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -86,6 +86,7 @@ static BOOL endTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment end. static BOOL rinsebackToStoppedRequest; ///< Flag indicates user has requested return to treatment from rinseback workflow. static BOOL endTreatmentRequest; ///< Flag indicates user has requested end of treatment from rinseback workflow. +static BOOL bloodPrimeToDialysisRequest; ///< Flag indicates blood prime has completed and time to start dialysis. static BOOL rinsebackToRecircRequest; ///< Flag indicates user has requested to proceed to re-circulate sub-mode. static BOOL treatmentEndToRinsebackRequest; ///< Flag indicates user has requested final rinseback. @@ -155,6 +156,7 @@ rinsebackToStoppedRequest = FALSE; endTreatmentRequest = FALSE; rinsebackToRecircRequest = FALSE; + bloodPrimeToDialysisRequest = FALSE; treatmentEndToRinsebackRequest = FALSE; } @@ -171,7 +173,7 @@ initTreatmentMode(); initTreatmentReservoirMgmt(); // Initialize treatment sub-modes each time we transition to treatment mode - // initBloodPrime(); TODO + initBloodPrime(); initDialysis(); initTreatmentStop(); initRinseback(); @@ -329,6 +331,19 @@ /*********************************************************************//** * @brief + * The signalBloodPrimeToDialysis function signals that blood prime has + * completed and it is time to move on to dialysis. + * @details Inputs: none + * @details Outputs: bloodPrimeToDialysisRequest + * @return none + *************************************************************************/ +void signalBloodPrimeToDialysis( void ) +{ + bloodPrimeToDialysisRequest = TRUE; +} + +/*********************************************************************//** + * @brief * The signalRinsebackToRecirc function signals that user wants to continue * on to re-circulate portion of rinseback workflow. * @details Inputs: none @@ -435,9 +450,7 @@ presMaxUFVolumeML = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) * (F32)ML_PER_LITER; presUFRate = presMaxUFVolumeML / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - // Kick dialysis sub-mode off - setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); - startDialysis(); + transitionToBloodPrime(); return result; } @@ -450,29 +463,30 @@ * @details Outputs: none * @return next treatment mode state *************************************************************************/ -static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ) // TODO - need separate module w/ states for this sub-mode (signal functions in treatment mode to be called if sub-mode chaning) +static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ) { TREATMENT_STATE_T result = TREATMENT_BLOOD_PRIME_STATE; setRinsebackIsCompleted( FALSE ); if ( TRUE == alarmStopSignalled ) { - alarmStopSignalled = FALSE; - // TODO - stopBloodPrime(); transitionToTreatmentStop(); result = TREATMENT_STOP_STATE; } else { - if ( TRUE ) // TODO - when blood prime done signal + if ( TRUE == bloodPrimeToDialysisRequest ) { setBloodIsPrimed( TRUE ); // TODO - call when blood prime is completed + // Kick dialysis sub-mode off + setDialysisParams( presBloodFlowRate, presDialysateFlowRate, presMaxUFVolumeML, presUFRate ); + startDialysis(); result = TREATMENT_DIALYSIS_STATE; } else { - //execTreatmentBloodPrime(); // TODO - implement this state + execBloodPrime(); } } @@ -497,7 +511,6 @@ // Handle alarm signals if ( TRUE == alarmStopSignalled ) { - alarmStopSignalled = FALSE; stopDialysis(); transitionToTreatmentStop(); result = TREATMENT_STOP_STATE; @@ -562,15 +575,12 @@ // If user requests rinseback, go to rinseback else if ( TRUE == initiateRinsebackAlarmResponseRequest ) { - initiateRinsebackAlarmResponseRequest = FALSE; transitionToRinseback(); result = TREATMENT_RINSEBACK_STATE; } // If user requests treatment end, end treatment else if ( TRUE == endTreatmentAlarmResponseRequest ) { - endTreatmentAlarmResponseRequest = FALSE; - // TODO - transition to end state result = TREATMENT_END_STATE; } // Otherwise execute state machine for treatment stop sub-mode @@ -597,7 +607,6 @@ // Handle alarm signals if ( TRUE == alarmStopSignalled ) { - alarmStopSignalled = FALSE; signalStopRinseback(); } @@ -652,7 +661,6 @@ } else if ( TRUE == endTreatmentRequest ) { - endTreatmentRequest = FALSE; result = TREATMENT_END_STATE; } Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -78,7 +78,7 @@ S32 venHighLimit; } PRESSURE_LIMIT_CHANGE_RESPONSE_T; -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initTreatmentMode( void ); // Initialize this module void transitionToTreatmentMode( void ); // Prepares for transition to treatment mode @@ -87,6 +87,7 @@ void signalGoToTreatmentStopped( void ); // Rinseback or Re-circ sub-mode is signaling to return to treatment stopped sub-mode void signalGoToRinseback( void ); // Requesting transition to rinseback sub-mode from other sub-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 void signalRinsebackToRecirc( void ); // Rinseback sub-mode is signaling to move on to re-circ sub-mode TREATMENT_STATE_T getTreatmentState( void ); // Determine the current treatment sub-mode (state) Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -17,7 +17,6 @@ #include "AirTrap.h" #include "BloodFlow.h" -#include "Buttons.h" #include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" @@ -44,16 +43,18 @@ #define RINSEBACK_FLOW_RATE_ADJ_ML_MIN 25 ///< Adjustment amount (in mL/min) to apply when user requests increase/decrease in flow rate. #define MIN_RINSEBACK_FLOW_RATE_ML_MIN 50 ///< Minimum rinseback flow rate (in mL/min). #define MAX_RINSEBACK_FLOW_RATE_ML_MIN 150 ///< Maximum rinseback flow rate (in mL/min). -#define MAX_RINSEBACK_SAFETY_VOLUME_MARGIN_PCT 1.2 ///< Maximum rinseback volume measured by independent means (as % of target). -#define MIN_RINSEBACK_SAFETY_VOLUME_MARGIN_PCT 0.8 ///< Minimum rinseback volume measured by independent means (as % of target). +/// Maximum rinseback volume measured by independent means (as % of target). +static const F32 MAX_RINSEBACK_SAFETY_VOLUME_ML = ( TARGET_RINSEBACK_VOLUME_ML * 1.2 ); +/// Minimum rinseback volume measured by independent means (as % of target). +static const F32 MIN_RINSEBACK_SAFETY_VOLUME_ML = ( TARGET_RINSEBACK_VOLUME_ML * 0.8 ); /// Interval at which rinseback progress is to be published to UI. #define RINSEBACK_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Maximum time allowed for rinseback operation (including additional rinseback volumes). #define MAX_RINSEBACK_TIME ( 7 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ) /// Maximum time allowed for each additional rinseback volume delivery. #define MAX_RINSEBACK_ADDITIONAL_TIME ( 15 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) - +/// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. static const F32 RINSEBACK_FLOW_INTEGRATOR = 1.0 / (F32)( SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); // ********** private data ********** @@ -300,7 +301,6 @@ // Has user requested rinseback start? if ( TRUE == startRinsebackRequested ) { - startRinsebackRequested = FALSE; setupForRinsebackDelivery( rinsebackRate_mL_min ); // From moment we start rinseback, we consider blood side of dialyzer no longer fully primed setBloodIsPrimed( FALSE ); @@ -354,14 +354,14 @@ setupForRinsebackStopOrPause(); result = RINSEBACK_STOP_STATE; } - // Has rinseback completed or user requested to end rinseback? + // Has rinseback completed? else if ( cumulativeRinsebackVolume_mL >= TARGET_RINSEBACK_VOLUME_ML ) { setRinsebackIsCompleted( TRUE ); setupForRinsebackStopOrPause(); result = RINSEBACK_STOP_STATE; // check for under-delivery - if ( rinsebackVolumeDelivered_Safety < ( TARGET_RINSEBACK_VOLUME_ML * MIN_RINSEBACK_SAFETY_VOLUME_MARGIN_PCT ) ) + if ( rinsebackVolumeDelivered_Safety < MIN_RINSEBACK_SAFETY_VOLUME_ML ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RINSEBACK_VOLUME_CHECK_FAILURE, TARGET_RINSEBACK_VOLUME_ML, rinsebackVolumeDelivered_Safety ); } @@ -388,7 +388,7 @@ result = RINSEBACK_PAUSED_STATE; } // Has independent safety volume exceeded safety limit? - else if ( rinsebackVolumeDelivered_Safety > ( TARGET_RINSEBACK_VOLUME_ML * MAX_RINSEBACK_SAFETY_VOLUME_MARGIN_PCT ) ) + else if ( rinsebackVolumeDelivered_Safety > MAX_RINSEBACK_SAFETY_VOLUME_ML ) { setRinsebackIsCompleted( TRUE ); setupForRinsebackStopOrPause(); Index: firmware/App/Modes/TreatmentEnd.c =================================================================== diff -u -r8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72) +++ firmware/App/Modes/TreatmentEnd.c (.../TreatmentEnd.c) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -17,14 +17,13 @@ #include "AirTrap.h" #include "BloodFlow.h" -#include "Buttons.h" #include "DialInFlow.h" #include "DialOutFlow.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" -#include "TreatmentStop.h" +#include "TreatmentEnd.h" #include "Valves.h" /** @@ -69,7 +68,7 @@ * The initTreatmentEnd function initializes the Treatment End sub-mode * module. * @details Inputs: none - * @details Outputs: Treatment Stop sub-mode module initialized. + * @details Outputs: Treatment End sub-mode module initialized. * @return none *************************************************************************/ void initTreatmentEnd( void ) Index: firmware/App/Modes/TreatmentEnd.h =================================================================== diff -u -r3d5a2ff09f3f4983699bfc61c7b63df1732970e0 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 3d5a2ff09f3f4983699bfc61c7b63df1732970e0) +++ firmware/App/Modes/TreatmentEnd.h (.../TreatmentEnd.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -34,7 +34,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initTreatmentEnd( void ); void transitionToTreatmentEnd( void ); Index: firmware/App/Modes/TreatmentRecirc.c =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/TreatmentRecirc.c (.../TreatmentRecirc.c) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/TreatmentRecirc.c (.../TreatmentRecirc.c) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -17,7 +17,6 @@ #include "AirTrap.h" #include "BloodFlow.h" -#include "Buttons.h" #include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" Index: firmware/App/Modes/TreatmentRecirc.h =================================================================== diff -u -r49dba1e95bb3763b4c150e7a80b84a65264a7ca8 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/TreatmentRecirc.h (.../TreatmentRecirc.h) (revision 49dba1e95bb3763b4c150e7a80b84a65264a7ca8) +++ firmware/App/Modes/TreatmentRecirc.h (.../TreatmentRecirc.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -31,7 +31,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initTreatmentRecirc( void ); void transitionToTreatmentRecirc( void ); Index: firmware/App/Modes/TreatmentStop.h =================================================================== diff -u -rc539499ea2dee6d62194d573ac93b313d9e2936d -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Modes/TreatmentStop.h (.../TreatmentStop.h) (revision c539499ea2dee6d62194d573ac93b313d9e2936d) +++ firmware/App/Modes/TreatmentStop.h (.../TreatmentStop.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -32,7 +32,7 @@ * @{ */ -// ********** private function prototypes ********** +// ********** public function prototypes ********** void initTreatmentStop( void ); void transitionToTreatmentStop( void ); Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -1216,6 +1216,34 @@ /***********************************************************************//** * @brief + * The broadcastBloodPrimeData function constructs a blood prime data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: blood prime data msg constructed and queued + * @param data blood prime data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastBloodPrimeData( BLOOD_PRIME_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_BLOOD_PRIME_PROGRESS; + msg.hdr.payloadLen = sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/***********************************************************************//** + * @brief * The broadcastAirTrapData function constructs an HD air trap data msg to \n * be broadcast and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72 -r1942c708bc95f57e87b0bf6a472ebe824a3f38ed --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 8000e5d68a7a0ed6d1b43d8e6778a246ff0d8e72) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 1942c708bc95f57e87b0bf6a472ebe824a3f38ed) @@ -21,6 +21,7 @@ #include "HDCommon.h" #include "AirTrap.h" #include "BloodFlow.h" +#include "BloodPrime.h" #include "DGInterface.h" #include "DialInFlow.h" #include "DialOutFlow.h" @@ -250,6 +251,9 @@ // MSG_ID_HD_RINSEBACK_PROGRESS BOOL broadcastRinsebackData( RINSEBACK_DATA_PAYLOAD_T data ); +// MSG_ID_HD_BLOOD_PRIME_PROGRESS +BOOL broadcastBloodPrimeData( BLOOD_PRIME_DATA_PAYLOAD_T data ); + // MSG_ID_HD_AIR_TRAP_DATA BOOL broadcastAirTrapData( AIR_TRAP_LEVELS_T lowerLevel, AIR_TRAP_LEVELS_T upperLevel );