Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r5e2d30dcbd02f5eb737aee7ec45c63d868daf252 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 5e2d30dcbd02f5eb737aee7ec45c63d868daf252) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file BloodFlow.c * -* @author (last) Sean Nash -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 08-Feb-2022 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -240,7 +240,7 @@ bpMotorSpeedCalcIdx = 0; for ( i = 0; i < BP_SPEED_CALC_BUFFER_LEN; i++ ) { - bpLastMotorHallSensorCounts[ i ] = 0; + bpLastMotorHallSensorCounts[ i ] = getFPGABloodPumpHallSensorCount(); } resetBloodPumpRotorCount(); Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,19 +1,20 @@ /************************************************************************** - * - * Copyright (c) 2019-2022 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 BloodLeak.c - * - * @author (last) Dara Navaei - * @date (last) 04-Jan-2022 - * - * @author (original) Peman Montazemi - * @date (original) 18-Mar-2021 - * - ***************************************************************************/ +* +* Copyright (c) 2021-2022 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 BloodLeak.c +* +* @author (last) Dara Navaei +* @date (last) 04-Jan-2022 +* +* @author (original) Peman Montazemi +* @date (original) 18-Mar-2021 +* +***************************************************************************/ + #include // For sprintf and strlen #include "AlarmMgmt.h" Index: firmware/App/Controllers/Bubble.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/Bubble.c (.../Bubble.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r5e2d30dcbd02f5eb737aee7ec45c63d868daf252 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 5e2d30dcbd02f5eb737aee7ec45c63d868daf252) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file DialInFlow.c * -* @author (last) Sean Nash -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 08-Feb-2022 * * @author (original) Sean * @date (original) 16-Dec-2019 @@ -237,7 +237,7 @@ dipMotorSpeedCalcIdx = 0; for ( i = 0; i < DIP_SPEED_CALC_BUFFER_LEN; i++ ) { - dipLastMotorHallSensorCounts[ i ] = 0; + dipLastMotorHallSensorCounts[ i ] = getFPGADialInPumpHallSensorCount(); } // Initialize dialysate inlet flow PI controller Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r5e2d30dcbd02f5eb737aee7ec45c63d868daf252 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 5e2d30dcbd02f5eb737aee7ec45c63d868daf252) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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 DialOutFlow.c * -* @author (last) Sean Nash -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Sean * @date (original) 24-Jan-2020 @@ -233,7 +233,7 @@ dopMotorSpeedCalcIdx = 0; for ( i = 0; i < DOP_SPEED_CALC_BUFFER__LEN; i++ ) { - dopLastMotorHallSensorCounts[ i ] = 0; + dopLastMotorHallSensorCounts[ i ] = getFPGADialOutPumpHallSensorCount(); } dopMeasuredRate = 0.0; Index: firmware/App/Controllers/DialOutFlow.h =================================================================== diff -u -r2acaf549519854f7e6de1511d541582267f4d1e8 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision 2acaf549519854f7e6de1511d541582267f4d1e8) +++ firmware/App/Controllers/DialOutFlow.h (.../DialOutFlow.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Controllers/Fans.c =================================================================== diff -u -r9e85e7ace1390d48587174a5bc6eb11d5185cea4 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Fans.c (.../Fans.c) (revision 9e85e7ace1390d48587174a5bc6eb11d5185cea4) +++ firmware/App/Controllers/Fans.c (.../Fans.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Controllers/Fans.h =================================================================== diff -u -r9c785a779da348df1c066ae0da2d0f53de7ea936 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Fans.h (.../Fans.h) (revision 9c785a779da348df1c066ae0da2d0f53de7ea936) +++ firmware/App/Controllers/Fans.h (.../Fans.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Controllers/FluidLeak.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/FluidLeak.c (.../FluidLeak.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/FluidLeak.c (.../FluidLeak.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r3d72b777cf1ceb673d118341c46e2d6d5b7b75f5 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 3d72b777cf1ceb673d118341c46e2d6d5b7b75f5) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -18,7 +18,8 @@ #include "PresOccl.h" #include "AlarmMgmt.h" #include "FPGA.h" -#include "ModeTreatmentParams.h" +#include "ModeTreatmentParams.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" @@ -45,7 +46,13 @@ #define VENOUS_PRESSURE_SCALE ( 14745 - VENOUS_PRESSURE_OFFSET ) ///< Scale for venous pressure sensor. #define VENOUS_PRESSURE_MIN_PSI ( -30.0 ) ///< Minimum of scale for venous pressure sensor reading (in PSI). #define VENOUS_PRESSURE_MAX_PSI ( 30.0 ) ///< Maximum of scale for venous pressure sensor reading (in PSI). +#define MIN_VENOUS_PRESSURE_FOR_RAMP_MMHG ( 0.0 ) ///< Minimum venous pressure during blood pump ramp up (in mmHg). +#define ARTERIAL_PRESSURE_OFFSET ( 1638 ) ///< Offset for 14-bit arterial pressure sensor reading. +#define ARTERIAL_PRESSURE_SCALE ( 14745 - VENOUS_PRESSURE_OFFSET ) ///< Scale for arterial pressure sensor. +#define ARTERIAL_PRESSURE_MIN_PSI ( -30.0 ) ///< Minimum of scale for arterial pressure sensor reading (in PSI). +#define ARTERIAL_PRESSURE_MAX_PSI ( 30.0 ) ///< Maximum of scale for arterial pressure sensor reading (in PSI). + #define ARTERIAL_PRESSURE_SELF_TEST_MIN ( -300.0 ) ///< Minimum self-test value for arterial pressure sensor reading (in mmHg). #define ARTERIAL_PRESSURE_SELF_TEST_MAX ( 100.0 ) ///< Maximum self-test value for arterial pressure sensor reading (in mmHg). #define ARTERIAL_PRESSURE_MAX_MMHG ( 2000.0 ) ///< Maximum arterial pressure reading (in mmHg) for range check. @@ -56,8 +63,7 @@ #define VENOUS_PRESSURE_MAX_MMHG ( 2000.0 ) ///< Maximum venous pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_MIN_MMHG ( -1500.0 ) ///< Minimum venous pressure reading (in mmHg) for range check. -#define VENOUS_PRESSURE_MIN_TEMP ( 0.0 ) ///< Minimum venous pressure sensor temperature. -#define VENOUS_PRESSURE_MAX_TEMP ( 80.0 ) ///< Maximum venous pressure sensor temperature. +#define MIN_OCCLUSION_COUNTS ( 2000 ) ///< Minimum occlusion sensor reading for range check. #define PSI_TO_MMHG ( 51.7149 ) ///< Conversion factor for converting PSI to mmHg. @@ -66,8 +72,15 @@ #define VENOUS_PRESSURE_STALE_DATA 2 ///< Venous pressure status bits indicate data is stale (no new data since last fpga read). #define VENOUS_PRESSURE_DIAG_CONDITION 3 ///< Venous pressure status bits diagnostic condition (alarm). -#define OCCLUSION_THRESHOLD_OFFSET 4000 ///< Threshold offset. Combined with initial reading after cartridge install, a threshold is derived above which an occlusion is detected. -#define OCCLUSION_CLEAR_THRESHOLD_OFFSET 4000 ///< Threshold offset. Combined with initial reading after cartridge install, a threshold is derived below which an occlusion is cleared. +// The new arterial pressure sensor is the same as the venous pressure sensor +#define ARTERIAL_PRESSURE_NORMAL_OP 0 ///< Arterial pressure status bits indicate normal operation. +#define ARTERIAL_PRESSURE_CMD_MODE 1 ///< Arterial pressure status bits indicate sensor in command mode. +#define ARTERIAL_PRESSURE_STALE_DATA 2 ///< Arterial pressure status bits indicate data is stale (no new data since last fpga read). +#define ARTERIAL_PRESSURE_DIAG_CONDITION 3 ///< Arterial pressure status bits diagnostic condition (alarm). + +#define OCCLUSION_THRESHOLD_OFFSET 10000 ///< Threshold offset. Combined with initial reading after cartridge install, a threshold is derived above which an occlusion is detected. +#define OCCLUSION_CLEAR_THRESHOLD_OFFSET 6000 ///< Threshold offset. Combined with initial reading after cartridge install, a threshold is derived below which an occlusion is cleared. + #define CARTRIDGE_LOADED_THRESHOLD 5000 ///< Threshold above which a cartridge is considered loaded. #define MIN_OCCLUSION_COUNTS 2000 ///< Minimum occlusion sensor reading for range check. #define MAX_OCCLUSION_COUNTS 32766 ///< Maximum occlusion sensor reading for range check. @@ -84,27 +97,30 @@ #define SIZE_OF_SHORT_ART_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) /// Measured venous pressure is filtered w/ 1 second moving average for inline pressure and unfiltered for occlusion detection. #define SIZE_OF_SHORT_VEN_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) + +#define DATA_PUBLISH_COUNTER_START_COUNT 5 ///< Data publish counter start count. +#define SHIFT_14_BITS 14 ///< Shift 14 bits. /// Defined states for the pressure and occlusion monitor state machine. typedef enum PresOccl_States { - PRESSURE_INIT_STATE = 0, ///< Initialization state. - PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. - NUM_OF_PRESSURE_STATES ///< Number of pressure/occlusion monitor states. + PRESSURE_WAIT_FOR_POST_STATE = 0, ///< Wait for POST state. + PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. + NUM_OF_PRESSURE_STATES ///< Number of pressure/occlusion monitor states. } PRESSURE_STATE_T; /// Defined states for the pressure and occlusion self-test state machine. typedef enum PresOccl_Self_Test_States { - PRESSURE_SELF_TEST_STATE_START = 0, ///< Self test start state. - PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. - PRESSURE_TEST_STATE_COMPLETE, ///< Self test completed state. - NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure/occlusion self-test states. + PRESSURE_SELF_TEST_STATE_START = 0, ///< Self test start state. + PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. + PRESSURE_TEST_STATE_COMPLETE, ///< Self test completed state. + NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure/occlusion self-test states. } PRESSURE_SELF_TEST_STATE_T; // ********** private data ********** -static PRESSURE_STATE_T presOcclState = PRESSURE_INIT_STATE; ///< Current state of pressure monitor state machine. +static PRESSURE_STATE_T presOcclState; ///< Current state of pressure monitor state machine. static U32 presOcclDataPublicationTimerCounter = 0; ///< Used to schedule pressure data publication to CAN bus. /// Interval (in ms) at which to publish pressure/occlusion data to CAN bus. @@ -117,18 +133,14 @@ static F32 shortFilteredArterialPressure; ///< Measured arterial pressure after short (1 s) filter. static F32 shortFilteredVenousPressure; ///< Measured venous pressure after short (1 s) filter. -#ifndef DISABLE_PRESSURE_CHECKS static U32 bloodPumpOcclusionAfterCartridgeInstall; ///< Measured blood pump occlusion reading taken after cartridge install. -#endif static U32 emptySalineBagCtr = 0; ///< Timer counter for empty bag detection. static U08 lastArterialPressureReadCtr; ///< Previous arterial pressure sensor read count. static U08 lastVenousPressureReadCtr; ///< Previous venous pressure sensor read count. -#ifndef DISABLE_PRESSURE_CHECKS static U08 lastBPOcclReadCtr; ///< Previous BP occlusion sensor read count. static U08 lastBPErrorCtr; ///< Previous BP error count. -#endif static F32 artPressureReadingsLong[ SIZE_OF_LONG_ART_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. static U32 artPressureReadingsLongIdx = 0; ///< Index for next sample in rolling average array. @@ -144,9 +156,13 @@ static U32 venPressureReadingsShortIdx = 0; ///< Index for next sample in rolling average array. static F32 venPressureReadingsShortTotal = 0.0; ///< Rolling total - used to calc average. static U32 venPressureReadingsShortCount = 0; ///< Number of samples in flow rolling average buffer. +static PRESSURE_SELF_TEST_STATE_T presOcclPostState; ///< Pressure self test post state. +static HD_PRESSURE_SENSORS_CAL_RECORD_T pressureSensorsCalRecord; ///< Pressure sensors calibration record. +static HD_OCCLUSION_SENSORS_CAL_RECORD_T occlusionSensorsCalRecord; ///< Occlusion sensors calibration record. // ********** private function prototypes ********** - + +static PRESSURE_STATE_T handlePresOcclWaitForPOSTState( void ); static PRESSURE_STATE_T handlePresOcclContReadState( void ); static void convertInlinePressures( void ); static void convertOcclusionPressures( void ); @@ -177,21 +193,28 @@ initPersistentAlarm( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, 0, PRES_ALARM_PERSISTENCE ); lastArterialPressureReadCtr = 0; - lastVenousPressureReadCtr = 0; -#ifndef DISABLE_PRESSURE_CHECKS - lastBPOcclReadCtr = 0; - lastBPErrorCtr = 0; -#endif + lastVenousPressureReadCtr = 0; + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + { + lastBPOcclReadCtr = 0; + lastBPErrorCtr = 0; + } - longFilteredArterialPressure = 0.0; - shortFilteredArterialPressure = 0.0; - shortFilteredVenousPressure = 0.0; + longFilteredArterialPressure = 0.0; + shortFilteredArterialPressure = 0.0; + shortFilteredVenousPressure = 0.0; + presOcclDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + presOcclState = PRESSURE_WAIT_FOR_POST_STATE; + presOcclPostState = PRESSURE_SELF_TEST_STATE_START; -#ifndef DISABLE_PRESSURE_CHECKS - bloodPumpOcclusionAfterCartridgeInstall = 0; -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + { + bloodPumpOcclusionAfterCartridgeInstall = 0; + } } /*********************************************************************//** @@ -270,9 +293,12 @@ *************************************************************************/ void setOcclusionInstallLevel( void ) { -#ifndef DISABLE_PRESSURE_CHECKS - bloodPumpOcclusionAfterCartridgeInstall = getMeasuredBloodPumpOcclusion(); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + bloodPumpOcclusionAfterCartridgeInstall = getMeasuredBloodPumpOcclusion(); + } } /*********************************************************************//** @@ -287,8 +313,8 @@ // State machine switch ( presOcclState ) { - case PRESSURE_INIT_STATE: - presOcclState = PRESSURE_CONTINUOUS_READ_STATE; + case PRESSURE_WAIT_FOR_POST_STATE: + presOcclState = handlePresOcclWaitForPOSTState(); break; case PRESSURE_CONTINUOUS_READ_STATE: @@ -302,6 +328,26 @@ // Publish pressure/occlusion data on interval publishPresOcclData(); +} + +/*********************************************************************//** + * @brief + * The handlePresOcclWaitForPOSTState function handles the wait for POST + * state. + * @details Inputs: presOcclPostState + * @details Outputs: none + * @return next state + *************************************************************************/ +static PRESSURE_STATE_T handlePresOcclWaitForPOSTState( void ) +{ + PRESSURE_STATE_T result = PRESSURE_WAIT_FOR_POST_STATE; + + if ( PRESSURE_TEST_STATE_COMPLETE == presOcclPostState ) + { + result = PRESSURE_CONTINUOUS_READ_STATE; + } + + return result; } /*********************************************************************//** @@ -342,26 +388,71 @@ *************************************************************************/ static void convertInlinePressures( void ) { - U32 fpgaArtPres = getFPGAArterialPressure(); - S32 artPres = (S32)( fpgaArtPres & MASK_OFF_U32_MSB ) - 0x800000; // Subtract 2^23 from low 24 bits to get signed reading - U08 artPresAlarm = (U08)( fpgaArtPres >> SHIFT_24_BITS ); // High byte is alarm code for arterial pressure - U16 fpgaVenPres = getFPGAVenousPressure(); - U16 venPres = fpgaVenPres & 0x3FFF; // 14-bit data - U08 venPresStatus = (U08)( fpgaVenPres >> 14 ); // High 2 bits is status code for venous pressure - F32 venPresPSI; - F32 venTemp = getTemperatureValue( TEMPSENSOR_VENOUS_PRESSURE_SENSOR ); - U08 venReadCtr = getFPGAVenousPressureReadCounter(); + F32 rawArterialPres = 0.0; + U08 artPresAlarm = 0; + U08 artPresStatus = 0; + F32 venPresPSI = 0.0; + U16 fpgaVenPres = getFPGAVenousPressure(); + U16 venPres = fpgaVenPres & 0x3FFF; // 14-bit data + U08 venPresStatus = (U08)( fpgaVenPres >> SHIFT_14_BITS ); // High 2 bits is status code for venous pressure + U08 venReadCtr = getFPGAVenousPressureReadCounter(); + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) + { + U16 fpgaArtPres = getFPGADVTArterialPressure(); + U16 artPres = fpgaArtPres & 0x3FFF; + rawArterialPres = (F32)artPres; + artPresStatus = (U08)( fpgaArtPres >> SHIFT_14_BITS ); + } + else + { + U32 fpgaArtPres = getFPGAArterialPressure(); + S32 artPres = (S32)( fpgaArtPres & MASK_OFF_U32_MSB ) - 0x800000; // Subtract 2^23 from low 24 bits to get signed reading + rawArterialPres = (F32)artPres; + artPresAlarm = (U08)( fpgaArtPres >> SHIFT_24_BITS ); // High byte is alarm code for arterial pressure + } + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) +#endif + { + if ( ARTERIAL_PRESSURE_NORMAL_OP == artPresStatus ) + { + U08 artReadCtr = getFPGADVTArterialPressureReadCounter(); + + // Check for stale venous pressure reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR ); + } + // Record arterial pressure sensor read counter for next time around + lastArterialPressureReadCtr = artReadCtr; + + arterialPressure.data = ( (F32)(rawArterialPres - ARTERIAL_PRESSURE_OFFSET) * + (ARTERIAL_PRESSURE_MAX_PSI - ARTERIAL_PRESSURE_MIN_PSI) / (F32)ARTERIAL_PRESSURE_SCALE ) + ARTERIAL_PRESSURE_MIN_PSI; + arterialPressure.data = arterialPressure.data * PSI_TO_MMHG; + } + else if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, TRUE ) ) + { + activateAlarmNoData( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); + } + else + { + resetPersistentAlarmTimer( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); + } + } // Convert arterial pressure to mmHg if no fault - if ( 0 == artPresAlarm ) + else if ( 0 == artPresAlarm ) { - U08 artReadCtr = getFPGAArterialPressureReadCounter(); + U08 artReadCtr = getFPGAArterialPressureReadCounter(); U08 artErrorCtr = getFPGAArterialPressureErrorCounter(); // Check for stale arterial pressure reading - if ( FALSE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr || artErrorCtr > 0 ) ) ) + // TODO I think we should check the change of the error count not if it is greater than 0? + if ( FALSE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr || artErrorCtr > 0 ) ) ) { - arterialPressure.data = ARTERIAL_PRESSURE_V_PER_BIT * ( (F32)(artPres) / ( ARTERIAL_PRESSURE_SENSITIVITY * ARTERIAL_PRESSURE_V_BIAS ) ) + getF32OverrideValue( &arterialPressureOffset ); + arterialPressure.data = ARTERIAL_PRESSURE_V_PER_BIT * ( rawArterialPres / ( ARTERIAL_PRESSURE_SENSITIVITY * ARTERIAL_PRESSURE_V_BIAS ) ) + + getF32OverrideValue( &arterialPressureOffset ); } else { @@ -372,9 +463,12 @@ } else { -#ifndef DISABLE_PRESSURE_CHECKS - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, (U32)artPresAlarm ) +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, (U32)artPresAlarm ) + } } // Check for stale venous pressure reading @@ -384,19 +478,29 @@ } // Record venous pressure sensor read counter for next time around lastVenousPressureReadCtr = venReadCtr; + // Convert venous pressure to PSI and then mmHg - venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX_PSI - VENOUS_PRESSURE_MIN_PSI) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN_PSI; + venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX_PSI - VENOUS_PRESSURE_MIN_PSI) / (F32)VENOUS_PRESSURE_SCALE ) + + VENOUS_PRESSURE_MIN_PSI; + // Convert venous pressure from PSI to mmHg if sensor status is normal if ( VENOUS_PRESSURE_NORMAL_OP == venPresStatus ) { venousPressure.data = venPresPSI * PSI_TO_MMHG; } // If venous pressure sensor status is not normal, fault +#ifndef _RELEASE_ + else if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, TRUE ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, (U32)venPresStatus ) + } + } else { -#ifndef DISABLE_PRESSURE_CHECKS -// SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, (U32)venPresStatus ) // TODO - persistence? YES, need persistence - getting a stale data status. OR maybe speed up ADC in FPGA. -#endif + resetPersistentAlarmTimer( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT ); } // Filter inline pressure readings @@ -412,31 +516,33 @@ *************************************************************************/ static void convertOcclusionPressures( void ) { - U08 bpReadCtr = getFPGABloodPumpOcclusionReadCounter(); - U08 bpErrorCtr = getFPGABloodPumpOcclusionErrorCounter(); + U08 bpReadCtr = getFPGABloodPumpOcclusionReadCounter(); + U08 bpErrorCtr = getFPGABloodPumpOcclusionErrorCounter(); -#ifndef DISABLE_PRESSURE_CHECKS - // Check for sensor errors - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, ( bpErrorCtr != lastBPErrorCtr ) ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, (U32)bpErrorCtr ) - } + // Check for sensor errors + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, ( bpErrorCtr != lastBPErrorCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, (U32)bpErrorCtr ) + } - // Check for stale occlusion reads - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, ( bpReadCtr == lastBPOcclReadCtr ) ) ) - { - activateAlarmNoData( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR ); + // Check for stale occlusion reads + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, ( bpReadCtr == lastBPOcclReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR ); + } } -#endif // Record occlusion sensor readings bloodPumpOcclusion.data = (U32)getFPGABloodPumpOcclusion(); -#ifndef DISABLE_PRESSURE_CHECKS - // Record occlusion read and error counters for next time around - lastBPOcclReadCtr = bpReadCtr; - lastBPErrorCtr = bpErrorCtr; -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + { + // Record occlusion read and error counters for next time around + lastBPOcclReadCtr = bpReadCtr; + lastBPErrorCtr = bpErrorCtr; + } } /*********************************************************************//** @@ -451,37 +557,45 @@ { F32 artPres = getFilteredArterialPressure(); -#ifndef DISABLE_ARTERIAL_PRESSURE_CHECK - // Check arterial pressure is in range - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, - ( artPres > ARTERIAL_PRESSURE_MAX_MMHG || artPres < ARTERIAL_PRESSURE_MIN_MMHG ) ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ARTERIAL_PRESSURE_CHECK ) != SW_CONFIG_ENABLE_VALUE ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres ); - } - - // Check arterial pressure during treatment mode - if ( ( MODE_TREA == getCurrentOperationMode() ) && ( getTreatmentState() <= TREATMENT_DIALYSIS_STATE ) ) - { - F32 artLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); - F32 artHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); - - // Check arterial pressure is within user set alarm limits - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres < artLowLimit ) ) + // Check arterial pressure is in range + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, + ( artPres > ARTERIAL_PRESSURE_MAX_MMHG || artPres < ARTERIAL_PRESSURE_MIN_MMHG ) ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres, artLowLimit ); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres ); } - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_HIGH, artPres > artHighLimit ) ) + // Check arterial pressure during treatment mode + if ( ( MODE_TREA == getCurrentOperationMode() ) && ( getTreatmentState() <= TREATMENT_DIALYSIS_STATE ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_ARTERIAL_PRESSURE_HIGH, artPres, artHighLimit ); + F32 artLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); + F32 artHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); + + // If BP is ramping up, extend range to outer limits as pressure may not yet have reached expected range. + if ( isBloodPumpRampComplete() != TRUE ) + { + artLowLimit = (F32)getS32TreatmentParamLowerRangeLimit( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); + artHighLimit = (F32)getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); + } + + // Check arterial pressure is within user set alarm limits + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres < artLowLimit ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_ARTERIAL_PRESSURE_LOW, artPres, artLowLimit ); + } + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_HIGH, artPres > artHighLimit ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_ARTERIAL_PRESSURE_HIGH, artPres, artHighLimit ); + } } + else + { // Reset persistence if alarm is out of scope + isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_LOW, FALSE ); + isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_HIGH, FALSE ); + } } - else - { // Reset persistence if alarm is out of scope - isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_LOW, FALSE ); - isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_HIGH, FALSE ); - } -#endif } /*********************************************************************//** @@ -496,44 +610,52 @@ { F32 venPres = getFilteredVenousPressure(); -#ifndef DISABLE_VENOUS_PRESSURE_CHECK - // Check venous pressure is in range - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres > VENOUS_PRESSURE_MAX_MMHG ) || - TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres < VENOUS_PRESSURE_MIN_MMHG ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_VENOUS_PRESSURE_CHECK ) != SW_CONFIG_ENABLE_VALUE ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres ); - } + // Check venous pressure is in range + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres > VENOUS_PRESSURE_MAX_MMHG ) || + TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres < VENOUS_PRESSURE_MIN_MMHG ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres ); + } - // Check venous pressure during treatment mode - if ( ( MODE_TREA == getCurrentOperationMode() ) && ( getTreatmentState() <= TREATMENT_DIALYSIS_STATE ) ) - { - F32 venLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ); - F32 venHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ); - - // Cannot monitor for low venous pressure while venting air trap - if ( getValveAirTrapStatus() != STATE_OPEN ) + // Check venous pressure during treatment mode + if ( ( MODE_TREA == getCurrentOperationMode() ) && ( getTreatmentState() <= TREATMENT_DIALYSIS_STATE ) ) { - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, venPres < venLowLimit ) ) + F32 venLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT ); + F32 venHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ); + + // If BP is ramping up, extend range to outer limits as pressure may not yet have reached expected range. + if ( isBloodPumpRampComplete() != TRUE ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_VENOUS_PRESSURE_LOW, venPres, venLowLimit ); + venLowLimit = MIN_VENOUS_PRESSURE_FOR_RAMP_MMHG; + venHighLimit = (F32)getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ); } + + // Cannot monitor for low venous pressure while venting air trap + if ( getValveAirTrapStatus() != STATE_OPEN ) + { + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, venPres < venLowLimit ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_VENOUS_PRESSURE_LOW, venPres, venLowLimit ); + } + } + else + { // clear persistence if air trap valve is open + isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, FALSE ); + } + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_HIGH, venPres > venHighLimit ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_VENOUS_PRESSURE_HIGH, venPres, venHighLimit ); + } } else - { // clear persistence if air trap valve is open + { // Reset persistence if alarm is out of scope isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, FALSE ); + isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_HIGH, FALSE ); } - - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_HIGH, venPres > venHighLimit ) ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_VENOUS_PRESSURE_HIGH, venPres, venHighLimit ); - } } - else - { // Reset persistence if alarm is out of scope - isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, FALSE ); - isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_HIGH, FALSE ); - } -#endif } /*********************************************************************//** @@ -549,24 +671,25 @@ U32 bpOccl = getMeasuredBloodPumpOcclusion(); BOOL outOfRange = ( bpOccl < MIN_OCCLUSION_COUNTS || bpOccl > MAX_OCCLUSION_COUNTS ? TRUE : FALSE ); -#ifndef DISABLE_PRESSURE_CHECKS - // Range check occlusion sensor - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, outOfRange ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl ); - } + // Range check occlusion sensor + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl < MIN_OCCLUSION_COUNTS ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl ); + } - // Check for occlusion - if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) - { - signalBloodPumpHardStop(); // Stop pump immediately - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) - } - else if ( bpOccl <= ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) - { - clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); + // Check for occlusion + if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + signalBloodPumpHardStop(); // Stop pump immediately + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + } + else if ( bpOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); + } } -#endif } /*********************************************************************//** @@ -747,26 +870,27 @@ *************************************************************************/ void execPresOcclTest( void ) { -#ifndef DISABLE_PRESSURE_CHECKS - U32 const bpPressure = getMeasuredBloodPumpOcclusion(); - F32 const arterialPressure = getFilteredArterialPressure(); - F32 const venousPressure = getFilteredVenousPressure(); + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) + { + U32 const bpPressure = getMeasuredBloodPumpOcclusion(); + F32 const arterialPressure = getFilteredArterialPressure(); + F32 const venousPressure = getFilteredVenousPressure(); - if ( bpPressure > CARTRIDGE_LOADED_THRESHOLD ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_SELF_TEST_FAILURE, bpPressure ); - } + if ( bpPressure > CARTRIDGE_LOADED_THRESHOLD ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_SELF_TEST_FAILURE, bpPressure ); + } - if ( ( arterialPressure <= ARTERIAL_PRESSURE_SELF_TEST_MIN ) || ( arterialPressure >= ARTERIAL_PRESSURE_SELF_TEST_MAX ) ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_SELF_TEST_FAILURE, arterialPressure ); - } + if ( ( arterialPressure <= ARTERIAL_PRESSURE_SELF_TEST_MIN ) || ( arterialPressure >= ARTERIAL_PRESSURE_SELF_TEST_MAX ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_SELF_TEST_FAILURE, arterialPressure ); + } - if ( ( venousPressure <= VENOUS_PRESSURE_SELF_TEST_MIN ) || ( venousPressure >= VENOUS_PRESSURE_SELF_TEST_MAX ) ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_SELF_TEST_FAILURE, venousPressure ); + if ( ( venousPressure <= VENOUS_PRESSURE_SELF_TEST_MIN ) || ( venousPressure >= VENOUS_PRESSURE_SELF_TEST_MAX ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_SELF_TEST_FAILURE, venousPressure ); + } } -#endif } /*********************************************************************//** @@ -780,15 +904,51 @@ { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; -#ifndef DISABLE_OCCLUSION_SELF_TEST - U32 const bpPressure = getMeasuredBloodPumpOcclusion(); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_OCCLUSION_SELF_TEST ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + U32 const bpPressure = getMeasuredBloodPumpOcclusion(); - if ( ( bpPressure <= CARTRIDGE_LOADED_THRESHOLD ) || ( bpPressure >= OCCLUSION_CARTRIDGE_LOADED_PRESSURE_READING_MAX ) ) + if ( ( bpPressure <= CARTRIDGE_LOADED_THRESHOLD ) || ( bpPressure >= OCCLUSION_CARTRIDGE_LOADED_PRESSURE_READING_MAX ) ) + { + activateAlarmNoData( ALARM_ID_NO_CARTRIDGE_LOADED ); + result = SELF_TEST_STATUS_FAILED; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The execPresOcclSelfTest function executes the PresOccl self-test. + * @details Inputs: none + * @details Outputs: pressureSensorsCalRecord, occlusionSensorsCalRecord + * @return the result of the PresOccl self-test. + *************************************************************************/ +SELF_TEST_STATUS_T execPresOcclSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; + BOOL calStatus = FALSE; + + // Get the pressure sensors and occlusion sensors calibration records + calStatus |= getNVRecord2Driver( GET_CAL_PRESSURE_SENSORS, (U08*)&pressureSensorsCalRecord, sizeof( HD_PRESSURE_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_HD_PRESSURE_SESNSORS, ALARM_ID_NO_ALARM ); + + calStatus |= getNVRecord2Driver( GET_CAL_OCCLUSION_SESNSORS, (U08*)&occlusionSensorsCalRecord, sizeof( HD_OCCLUSION_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_OCCLUSION_SENSORS, ALARM_ID_NO_ALARM ); + + presOcclPostState = PRESSURE_TEST_STATE_COMPLETE; + + if ( TRUE == calStatus ) { - activateAlarmNoData( ALARM_ID_NO_CARTRIDGE_LOADED ); + result = SELF_TEST_STATUS_PASSED; + } + else + { result = SELF_TEST_STATUS_FAILED; } -#endif return result; } Index: firmware/App/Controllers/PresOccl.h =================================================================== diff -u -r2acaf549519854f7e6de1511d541582267f4d1e8 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision 2acaf549519854f7e6de1511d541582267f4d1e8) +++ firmware/App/Controllers/PresOccl.h (.../PresOccl.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Controllers/Switches.c =================================================================== diff -u -r9e85e7ace1390d48587174a5bc6eb11d5185cea4 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Switches.c (.../Switches.c) (revision 9e85e7ace1390d48587174a5bc6eb11d5185cea4) +++ firmware/App/Controllers/Switches.c (.../Switches.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,41 +1,41 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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 SyringePump.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Hung Nguyen +* @date (last) 15-Feb-2022 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 * ***************************************************************************/ #include - -#include "AlarmMgmt.h" + +#include "AlarmMgmt.h" #include "FPGA.h" #include "ModeTreatmentParams.h" -#include "NVDataMgmt.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SafetyShutdown.h" -#include "SyringePump.h" -#include "SystemCommMessages.h" -#include "TaskPriority.h" -#include "Timers.h" - -/** - * @addtogroup SyringePump - * @{ - */ - -// ********** private definitions ********** - -/// Default publication interval for syringe pump data. +#include "SyringePump.h" +#include "SystemCommMessages.h" +#include "TaskPriority.h" +#include "Timers.h" + +/** + * @addtogroup SyringePump + * @{ + */ + +// ********** private definitions ********** + +/// Default publication interval for syringe pump data. #define SYRINGE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) #define BD_SYRINGE_ID_RADIUS_CM ( 1.4427 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. @@ -55,20 +55,18 @@ /// Number of encoder counts per mL. #define SYRINGE_ENCODER_COUNTS_PER_ML ( SYRINGE_ENCODER_COUNTS_PER_MM / SYRINGE_ML_PER_MM ) /// Number of micro steps per mL. -#define SYRINGE_MICRO_STEPS_PER_ML ( ( SYRINGE_MICRO_STEPS_PER_REV / SYRINGE_MM_PER_REV ) / SYRINGE_ML_PER_MM ) +#define SYRINGE_MICRO_STEPS_PER_ML ( ( SYRINGE_MICRO_STEPS_PER_REV / SYRINGE_MM_PER_REV ) / SYRINGE_ML_PER_MM ) #define MIN_HEPARIN_CONTINUOUS_RATE 0.2 ///< Minimum continuous Heparin flow rate (in mL/hr). #define MAX_HEPARIN_CONTINUOUS_RATE 1.0 ///< Maximum continuous Heparin flow rate (in mL/hr). -#define MIN_HEPARIN_BOLUS_RATE 1.2 ///< Minimum Heparin bolus flow rate (in mL/hr). -#define MAX_HEPARIN_BOLUS_RATE 24.0 ///< Maximum Heparin bolus flow rate (in mL/hr). -#define HEPARIN_BOLUS_TIME_HR ( 5.0 / MIN_PER_HOUR ) ///< Duration (in hours) of Heparin bolus. +#define HEPARIN_BOLUS_TARGET_RATE 40.0 ///< Heparin bolus target rate (in ml/hr); #define SYRINGE_PUMP_RETRACT_RATE 3600.0 ///< Retract rate is 5 mL/ 5 s = 1 mL/s = 3,600 mL/hr. #define SYRINGE_PUMP_SEEK_RATE 3600.0 ///< Seek plunger rate is 5 mL/ 5 s = 1 mL/s = 3,600 mL/hr. #define SYRINGE_PUMP_PRIME_RATE 635.0 ///< Prime rate is 0.5 mm ^ 2 x PI x 450 mm = 0.353 mL / 2s = 635 mL/hr. #define SYRINGE_PUMP_MAX_RATE 11000.0 ///< Maximum rate of the syringe pump (in mL/hr). -#define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 2000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. -#define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. +#define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. +#define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. #define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. #define SYRINGE_PUMP_OCCLUSION_ALARM_PERSISTENCE 30 ///< Alarm persistence period (in ms) for syringe pump occlusion alarms. #define SYRINGE_PUMP_ADC_READ_PERSISTENCE 100 ///< Syringe pump ADC stale read alarm persistence time (in ms). @@ -81,6 +79,7 @@ #define SYRINGE_PUMP_DAC_FULL_SCALE_BITS 4096.0 ///< Syringe pump DAC has has 4096 full scale counts (12-bit). #define SYRINGE_FORCE_OCCLUSION_THRESHOLD_V 3.2 ///< Force sensor threshold (in V) above which an occlusion is detected. +#define SYRINGE_FORCE_OCCLUSION_DIFF_V 0.5 ///< Force sensor difference (in V) which an occlusion alarm is triggered. #define SYRINGE_FORCE_PLUNGER_THRESHOLD_V 0.25 ///< Force sensor threshold (in V) above which we have engaged with plunger. #define SYRINGE_PUMP_SYRINGE_DETECT_THRESHOLD_V 2.0 ///< Syringe pump syringe detected threshold (in V). #define SYRINGE_PUMP_HOME_DETECT_THRESHOLD_V 0.25 ///< Syringe pump home detected threshold (in V). @@ -90,7 +89,7 @@ #define TEN_PCT_OVER_ALLOWANCE 1.1 ///< Allow 10 percent over target before alarming on over travel. #define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow 5 percent over target before alarming on over travel. -/// Expected position of empty in relation to home postion. +/// Expected position of empty in relation to home position. #define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) @@ -127,7 +126,7 @@ #define SYRINGE_PUMP_MICROSTEP_TOGGLE_TIME_FOR_STOP 0xFFFFFFFF ///< Syringe pump microstep toggle time setting to indicate zero speed (stopped). #define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. - + /// Control bits to run syringe pump in reverse direction static const U08 SYRINGE_PUMP_CONTROL_RUN_REVERSE = SYRINGE_PUMP_CONTROL_SLEEP_OFF | SYRINGE_PUMP_CONTROL_NOT_RESET | @@ -154,41 +153,44 @@ #define SYRINGE_PUMP_RAMP_STALL_RETRIES 3 ///< Syringe pump ramp stall retries allowed. #define SYRINGE_PUMP_STALL_SPEED_THRESHOLD 0.05 ///< Minimum syringe pump speed to be considered not stalled. -/// Defined states for the syringe pump control state machine. -typedef enum SyringePump_States -{ +/// Defined states for the syringe pump control state machine. +typedef enum SyringePump_States +{ SYRINGE_PUMP_INIT_STATE = 0, ///< Syringe pump initialize state - SYRINGE_PUMP_OFF_STATE, ///< Syringe pump off state + SYRINGE_PUMP_OFF_STATE, ///< Syringe pump off state SYRINGE_PUMP_RETRACT_STATE, ///< Syringe pump retract state SYRINGE_PUMP_SEEK_STATE, ///< Syringe pump seek plunger state SYRINGE_PUMP_PRIME_STATE, ///< Syringe pump prime state SYRINGE_PUMP_HEP_BOLUS_STATE, ///< Syringe pump bolus delivery of Heparin state SYRINGE_PUMP_HEP_CONTINUOUS_STATE, ///< Syringe pump continuous delivery of Heparin state SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE, ///< Syringe pump configure DAC gain for force sensor state - NUM_OF_SYRINGE_PUMP_STATES ///< Number of syringe pump control states -} SYRINGE_PUMP_STATE_T; - -// ********** private data ********** - -static SYRINGE_PUMP_STATE_T syringePumpState; ///< Current state of syringe pump control state machine. + NUM_OF_SYRINGE_PUMP_STATES ///< Number of syringe pump control states +} SYRINGE_PUMP_STATE_T; + +// ********** private data ********** + +static SYRINGE_PUMP_STATE_T syringePumpState; ///< Current state of syringe pump control state machine. static U32 syringePumpDataPublicationTimerCounter; ///< Used to schedule syringe pump data publication to CAN bus. static U32 syringePumpRampTimerCtr; ///< Used to track ramp up time. static HEPARIN_STATE_T heparinDeliveryState; ///< Current state of Heparin delivery. - + /// Interval (in ms) at which to publish syringe pump data to CAN bus. -static OVERRIDE_U32_T syringePumpDataPublishInterval = { SYRINGE_PUMP_DATA_PUB_INTERVAL, SYRINGE_PUMP_DATA_PUB_INTERVAL, 0, 0 }; -static OVERRIDE_F32_T syringePumpMeasRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured rate for syringe pump (in mL/hr). -static OVERRIDE_F32_T syringePumpMeasForce = { 0.0, 0.0, 0.0, 0 }; ///< Measured driver force (in V). -static OVERRIDE_F32_T syringePumpMeasSyringeDetectionSwitch = { 0, 0, 0, 0 }; ///< Measured syringe detect switch (in V). +static OVERRIDE_U32_T syringePumpDataPublishInterval = { SYRINGE_PUMP_DATA_PUB_INTERVAL, SYRINGE_PUMP_DATA_PUB_INTERVAL, 0, 0 }; +static OVERRIDE_F32_T syringePumpMeasRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured rate for syringe pump (in mL/hr). +static OVERRIDE_F32_T syringePumpMeasForce = { 0.0, 0.0, 0.0, 0 }; ///< Measured driver force (in V). +static OVERRIDE_F32_T syringePumpMeasSyringeDetectionSwitch = { 0, 0, 0, 0 }; ///< Measured syringe detect switch (in V). static OVERRIDE_F32_T syringePumpMeasHome = { 0.0, 0.0, 0.0, 0 }; ///< Measured optical home (in V). static OVERRIDE_S32_T syringePumpPosition = { 0, 0, 0, 0 }; ///< Encoder based position (in steps). static OVERRIDE_F32_T syringePumpVolumeDelivered = { 0.0, 0.0, 0.0, 0 }; ///< Measured volume delivered (in mL). +static OVERRIDE_F32_T heparinBolusTargetRate = { HEPARIN_BOLUS_TARGET_RATE, 0.0, HEPARIN_BOLUS_TARGET_RATE, 0 }; ///< Target rate of the heprin bolus in mL/hour + static OVERRIDE_U32_T syringePumpStatus = {0, 0, 0, 0}; ///< Syringe pump status reported by FPGA. static OVERRIDE_U32_T syringePumpEncoderStatus = {0, 0, 0, 0}; ///< Syringe pump encoder status reported by FPGA. static OVERRIDE_U32_T syringePumpADCandDACStatus = {0, 0, 0, 0}; ///< Syringe pump ADC and DAC status reported by FPGA. static OVERRIDE_U32_T syringePumpADCReadCtr = {0, 0, 0, 0}; ///< Syringe pump ADC read counter reported by FPGA. static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). +static F32 forceAtEndOfSeek; ///< Force sensor reading in Volts at the end of seek. static U32 syringePumpSetToggleTime; ///< Set rate for syringe pump (in uSec/toggle). static U32 syringePumpRampUpToggleTime; ///< Current ramp rate for syringe pump (in uSec/toggle). static F32 syringePumpSafetyVolumeDelivered; ///< Calculated volume (in mL) (from set rate over time). @@ -222,20 +224,22 @@ static U32 syringePumpStallRetryCount; ///< Counts pump ramp up stall retries. static HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T forceSensorCalRecord; ///< HD heparin force sensor calibration record. -// ********** private function prototypes ********** +// ********** private function prototypes ********** static void resetSyringePumpRequestFlags( void ); -static void execSyringePumpMonitor( void ); +static void execSyringePumpMonitor( void ); static S32 getSyringePumpPosition( void ); static F32 getSyringePumpMeasRate( void ); static F32 getSyringePumpSyringeDetectorV( void ); static F32 getSyringePumpHomeDetectorV( void ); static F32 getSyringePumpForceV( void ); +static F32 getHeprinBolusTargetRate( void ); static U08 getSyringePumpStatus( void ); static U08 getSyringePumpEncoderStatus( void ); static U08 getSyringePumpADCReadCounter( void ); static U08 getSyringePumpADCandDACStatus( void ); -static SYRINGE_PUMP_STATE_T handleSyringePumpInitState( void ); + +static SYRINGE_PUMP_STATE_T handleSyringePumpInitState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpOffState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpRetractState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpSeekState( void ); @@ -248,22 +252,22 @@ static void calcMeasRate( void ); static void calcSafetyVolumeDelivered( void ); static BOOL checkDirection( BOOL stopPump, MOTOR_DIR_T expDir ); -static BOOL checkOcclusionOrEmpty( BOOL stopPump ); +static BOOL checkSyringeEmpty( BOOL stopPump ); static BOOL checkSyringeRemoved( BOOL stopPump ); static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ); static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ); static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static BOOL checkForStall( BOOL stopPump ); static void publishSyringePumpData( void ); - -/*********************************************************************//** - * @brief - * The initSyringePump function initializes the syringe pump module. - * @details Inputs: none - * @details Outputs: syringe pump module initialized. - * @return none - *************************************************************************/ -void initSyringePump( void ) + +/*********************************************************************//** + * @brief + * The initSyringePump function initializes the syringe pump module. + * @details Inputs: none + * @details Outputs: syringe pump module initialized. + * @return none + *************************************************************************/ +void initSyringePump( void ) { U32 i; @@ -312,7 +316,7 @@ initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, 0, SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, 0, SYRINGE_PUMP_OCCLUSION_ALARM_PERSISTENCE ); - // Reset request flags + // Reset request flags resetSyringePumpRequestFlags(); } @@ -522,6 +526,7 @@ if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) && ( TRUE == syringePumpPlungerFound ) ) { + forceAtEndOfSeek = getSyringePumpForceV(); // Get the force sensor reading when syringe pump prime has been requested (after seek) syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; syringePumpPrimeRequested = TRUE; resetHeparinVolumeDelivered(); @@ -554,26 +559,21 @@ *************************************************************************/ BOOL startHeparinBolus( void ) { - F32 tgtRate = 0.0; - - // Get set Heparin bolus volume (mL) and convert to target rate (mL/hr) - tgtRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) / HEPARIN_BOLUS_TIME_HR; - // If valid to start a bolus, kick it off - if ( ( tgtRate >= MIN_HEPARIN_BOLUS_RATE ) && ( tgtRate <= MAX_HEPARIN_BOLUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) + if ( FALSE == isSyringePumpHome() ) { if ( ( TRUE == isSyringeDetected() ) && ( TRUE == syringePumpPrimeCompleted ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) ) { - syringePumpSetRate = tgtRate; + syringePumpSetRate = getHeprinBolusTargetRate(); syringePumpBolusRequested = TRUE; } } else { if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) != SW_CONFIG_ENABLE_VALUE ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_BOLUS_CMD, tgtRate ) + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_BOLUS_CMD, syringePumpSetRate ) } } @@ -647,14 +647,7 @@ *************************************************************************/ F32 getSyringePumpVolumeDelivered( void ) { - F32 result = syringePumpVolumeDelivered.data; - - if ( OVERRIDE_KEY == syringePumpVolumeDelivered.override ) - { - result = syringePumpVolumeDelivered.ovData; - } - - return result; + return getF32OverrideValue( &syringePumpVolumeDelivered ); } /*********************************************************************//** @@ -667,38 +660,11 @@ *************************************************************************/ static F32 getSyringePumpMeasRate( void ) { - F32 result = syringePumpMeasRate.data; - - if ( OVERRIDE_KEY == syringePumpMeasRate.override ) - { - result = syringePumpMeasRate.ovData; - } - - return result; + return getF32OverrideValue( &syringePumpMeasRate ); } /*********************************************************************//** * @brief - * The getSyringePumpPosition function gets the current syringe pump - * position. - * @details Inputs: syringePumpPosition - * @details Outputs: none - * @return the current syringe pump syringe position (in steps). - *************************************************************************/ -static S32 getSyringePumpPosition( void ) -{ - S32 result = syringePumpPosition.data; - - if ( OVERRIDE_KEY == syringePumpPosition.override ) - { - result = syringePumpPosition.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief * The getSyringePumpSyringeDetectorV function gets the current syringe pump * syringe detect signal. * @details Inputs: syringePumpMeasSyringeDetectionSwitch @@ -707,14 +673,7 @@ *************************************************************************/ static F32 getSyringePumpSyringeDetectorV( void ) { - F32 result = syringePumpMeasSyringeDetectionSwitch.data; - - if ( OVERRIDE_KEY == syringePumpMeasSyringeDetectionSwitch.override ) - { - result = syringePumpMeasSyringeDetectionSwitch.ovData; - } - - return result; + return getF32OverrideValue( &syringePumpMeasSyringeDetectionSwitch ); } /*********************************************************************//** @@ -727,14 +686,7 @@ *************************************************************************/ static F32 getSyringePumpHomeDetectorV( void ) { - F32 result = syringePumpMeasHome.data; - - if ( OVERRIDE_KEY == syringePumpMeasHome.override ) - { - result = syringePumpMeasHome.ovData; - } - - return result; + return getF32OverrideValue( &syringePumpMeasHome ); } /*********************************************************************//** @@ -746,14 +698,33 @@ *************************************************************************/ static F32 getSyringePumpForceV( void ) { - F32 result = syringePumpMeasForce.data; + return getF32OverrideValue( &syringePumpMeasForce ); +} - if ( OVERRIDE_KEY == syringePumpMeasForce.override ) - { - result = syringePumpMeasForce.ovData; - } +/*********************************************************************//** + * @brief + * The getHeprinBolusTargetRate function gets the heprin bolus target + * flow rate. + * @details Inputs: getHeprinBolusTargetRate + * @details Outputs: getHeprinBolusTargetRate + * @return the current target heprin bolus flow rate (in mL/hour). + *************************************************************************/ +static F32 getHeprinBolusTargetRate( void ) +{ + return getF32OverrideValue( &heparinBolusTargetRate ); +} - return result; +/*********************************************************************//** + * @brief + * The getSyringePumpPosition function gets the current syringe pump + * position. + * @details Inputs: syringePumpPosition + * @details Outputs: none + * @return the current syringe pump syringe position (in steps). + *************************************************************************/ +static S32 getSyringePumpPosition( void ) +{ + return getS32OverrideValue( &syringePumpPosition ); } /*********************************************************************//** @@ -765,14 +736,7 @@ *************************************************************************/ static U08 getSyringePumpStatus() { - U08 result = (U08)(syringePumpStatus.data & MASK_OFF_U32_MSBS); - - if ( OVERRIDE_KEY == syringePumpStatus.override ) - { - result = (U08)(syringePumpStatus.ovData & MASK_OFF_U32_MSBS); - } - - return result; + return getU08OverrideValue( &syringePumpStatus ); } /*********************************************************************//** @@ -785,14 +749,7 @@ *************************************************************************/ static U08 getSyringePumpEncoderStatus() { - U08 result = (U08)(syringePumpEncoderStatus.data & MASK_OFF_U32_MSBS); - - if ( OVERRIDE_KEY == syringePumpEncoderStatus.override ) - { - result = (U08)(syringePumpEncoderStatus.ovData & MASK_OFF_U32_MSBS); - } - - return result; + return getU08OverrideValue( &syringePumpEncoderStatus ); } /*********************************************************************//** @@ -805,14 +762,7 @@ *************************************************************************/ static U08 getSyringePumpADCReadCounter() { - U08 result = (U08)(syringePumpADCReadCtr.data & MASK_OFF_U32_MSBS); - - if ( OVERRIDE_KEY == syringePumpADCReadCtr.override ) - { - result = (U08)(syringePumpADCReadCtr.ovData & MASK_OFF_U32_MSBS); - } - - return result; + return getU08OverrideValue( &syringePumpADCReadCtr ); } /*********************************************************************//** @@ -825,14 +775,7 @@ *************************************************************************/ static U08 getSyringePumpADCandDACStatus() { - U08 result = (U08)(syringePumpADCandDACStatus.data & MASK_OFF_U32_MSBS); - - if ( OVERRIDE_KEY == syringePumpADCandDACStatus.override ) - { - result = (U08)(syringePumpADCandDACStatus.ovData & MASK_OFF_U32_MSBS); - } - - return result; + return getU08OverrideValue( &syringePumpADCandDACStatus ); } /*********************************************************************//** @@ -1012,8 +955,7 @@ // Check if syringe pump is on while BP is off { - BOOL runWhileOff = ( ( ( SYRINGE_PUMP_HEP_BOLUS_STATE == syringePumpState ) || ( SYRINGE_PUMP_HEP_CONTINUOUS_STATE == syringePumpState ) ) && - ( isBloodPumpRunning() != TRUE ) ); + BOOL runWhileOff = ( ( SYRINGE_PUMP_HEP_CONTINUOUS_STATE == syringePumpState ) && ( isBloodPumpRunning() != TRUE ) ); if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_RUNNING_WHILE_BP_OFF_ERROR, runWhileOff ) ) { @@ -1043,14 +985,14 @@ } } -/*********************************************************************//** - * @brief - * The execSyringePump function executes the syringe pump control state machine. - * @details Inputs: syringePumpState - * @details Outputs: syringePumpState - * @return none - *************************************************************************/ -void execSyringePump( void ) +/*********************************************************************//** + * @brief + * The execSyringePump function executes the syringe pump control state machine. + * @details Inputs: syringePumpState + * @details Outputs: syringePumpState + * @return none + *************************************************************************/ +void execSyringePump( void ) { // Execute syringe pump monitor execSyringePumpMonitor(); @@ -1060,18 +1002,18 @@ { isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, FALSE ); } - - // Execute syringe pump control state machine - switch ( syringePumpState ) - { - case SYRINGE_PUMP_INIT_STATE: - syringePumpState = handleSyringePumpInitState(); - break; - - case SYRINGE_PUMP_OFF_STATE: - syringePumpState = handleSyringePumpOffState(); - break; - + + // Execute syringe pump control state machine + switch ( syringePumpState ) + { + case SYRINGE_PUMP_INIT_STATE: + syringePumpState = handleSyringePumpInitState(); + break; + + case SYRINGE_PUMP_OFF_STATE: + syringePumpState = handleSyringePumpOffState(); + break; + case SYRINGE_PUMP_RETRACT_STATE: syringePumpState = handleSyringePumpRetractState(); break; @@ -1096,15 +1038,15 @@ syringePumpState = handleSyringePumpCalibrateForceSensorState(); break; - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_SYRINGE_INVALID_STATE, syringePumpState ) - break; - } + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_SYRINGE_INVALID_STATE, syringePumpState ) + break; + } resetSyringePumpRequestFlags(); - - // Publish syringe pump data on interval - publishSyringePumpData(); + + // Publish syringe pump data on interval + publishSyringePumpData(); } /*********************************************************************//** @@ -1133,7 +1075,7 @@ } return result; -} +} /*********************************************************************//** * @brief @@ -1312,7 +1254,7 @@ F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; + F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ); F32 txVolume = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_ENCODER_COUNTS_PER_ML; @@ -1323,14 +1265,14 @@ if ( ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) || ( syringeVol < txVolume ) ) { stopPump = TRUE; - syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = pos; // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm if ( syringeVol >= txVolume ) { + syringePumpPlungerFound = TRUE; syringeVolumeAdequate = TRUE; } else @@ -1390,16 +1332,13 @@ // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); - // Check position > max travel stopPump = checkMaxTravel( stopPump, syringePumpVolumeStartPosition + ( SYRINGE_PUMP_PRIME_VOLUME_ML * TEN_PCT_OVER_ALLOWANCE * SYRINGE_ENCODER_COUNTS_PER_ML ) ); // Check pump direction stopPump = checkDirection( stopPump, MOTOR_DIR_FORWARD ); - // If anything found that would require stopping the pump, stop pump and go to off state + // If anything found that would require stopping the pump, stop pump if ( TRUE == stopPump ) { stopSyringePump(); @@ -1437,8 +1376,8 @@ // Check volume vs. safety volume stopPump = checkVolumeVsSafetyVolume( stopPump, SYRINGE_PUMP_VOLUME_CHECK_MARGIN ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); + // Check for syringe pump empty + stopPump = checkSyringeEmpty( stopPump ); // Check for commanded vs. meas. rate stopPump = checkMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); @@ -1478,8 +1417,8 @@ // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); + // Check for syringe pump empty + stopPump = checkSyringeEmpty( stopPump ); // Check position > empty + 0.5 mL stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); @@ -1568,32 +1507,50 @@ /*********************************************************************//** * @brief - * The checkOcclusionOrEmpty function checks the force sensor for excessive - * pressure. Would indicate occlusion or jam or empty syringe. + * The checkSyringeEmpty function checks the force sensor position + * to determine if the syringe pump is empty. * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data - * @details Outputs: alarm triggered if max force detected + * @details Outputs: alarm triggered if position is empty. * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if pump should be stopped, FALSE if not *************************************************************************/ -static BOOL checkOcclusionOrEmpty( BOOL stopPump ) +static BOOL checkSyringeEmpty( BOOL stopPump ) { BOOL result = stopPump; F32 force = getSyringePumpForceV(); + S32 pos = getSyringePumpPosition(); - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, ( force >= SYRINGE_FORCE_OCCLUSION_THRESHOLD_V ) ) ) + // If near empty position, assume syringe is empty + if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) { - S32 pos = getSyringePumpPosition(); + heparinDeliveryState = HEPARIN_STATE_EMPTY; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) + result = TRUE; + } - // If near empty position, assume syringe is empty - if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) - { - heparinDeliveryState = HEPARIN_STATE_EMPTY; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) - } - else - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, (F32)pos, force ) - } + return result; +} + +/*********************************************************************//** + * @brief + * The checkForPrimeOcclusion function checks the force sensor for excessive + * pressure. Would indicate occlusion or jam or empty syringe. + * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data + * @details Outputs: alarm triggered if max force detected + * @param stopPump flag passed in by caller indicating whether pump should be stopped + * @return TRUE if pump should be stopped, FALSE if not + *************************************************************************/ +BOOL checkForPrimeOcclusion( void ) +{ + BOOL result = FALSE; // Return FALSE if no occlusion is detected + F32 forceAtEndOfPriming = getSyringePumpForceV(); // Read the force sensor at the end of the priming + F32 forceDelta = forceAtEndOfPriming - forceAtEndOfSeek; // Occlusion is detected if force at end of prime is > than force at end of seek by 0.5 volts or more + BOOL occlusionDetected = ( forceDelta >= SYRINGE_FORCE_OCCLUSION_DIFF_V ? TRUE : FALSE ); + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, occlusionDetected ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, forceAtEndOfPriming ) // reuse this alarm after prime + forceAtEndOfSeek = 0.0; // reset this value in case we want to prime again result = TRUE; } @@ -1787,7 +1744,7 @@ } } } - + /*********************************************************************//** * @brief * The calcStepperToggleTimeForTargetRate function calculates the stepper @@ -1858,18 +1815,18 @@ syringePumpSafetyVolumeDelivered += ( syringePumpSetRate / ( MIN_PER_HOUR * SEC_PER_MIN * ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ) ); } -/*********************************************************************//** - * @brief - * The publishSyringePumpData function publishes syringe pump data at the - * set interval. - * @details Inputs: latest syringe pump data, syringePumpDataPublicationTimerCounter - * @details Outputs: Syringe pump data are published to CAN bus. - * @return none - *************************************************************************/ -static void publishSyringePumpData( void ) -{ - // Publish syringe pump data on interval - if ( ++syringePumpDataPublicationTimerCounter >= getU32OverrideValue( &syringePumpDataPublishInterval ) ) +/*********************************************************************//** + * @brief + * The publishSyringePumpData function publishes syringe pump data at the + * set interval. + * @details Inputs: latest syringe pump data, syringePumpDataPublicationTimerCounter + * @details Outputs: Syringe pump data are published to CAN bus. + * @return none + *************************************************************************/ +static void publishSyringePumpData( void ) +{ + // Publish syringe pump data on interval + if ( ++syringePumpDataPublicationTimerCounter >= getU32OverrideValue( &syringePumpDataPublishInterval ) ) { SYRINGE_PUMP_DATA_PAYLOAD_T data; @@ -1887,68 +1844,67 @@ ( (U32)getSyringePumpEncoderStatus() << SHIFT_16_BITS_FOR_WORD_SHIFT ) | ( (U32)getSyringePumpADCandDACStatus() << SHIFT_8_BITS_FOR_BYTE_SHIFT ) | ( (U32)getSyringePumpADCReadCounter() ); - + broadcastData( MSG_ID_HD_SYRINGE_PUMP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ) ); broadcastData( MSG_ID_HD_HEPARIN_DATA_BROADCAST, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data.syringePumpVolumeDelivered, sizeof( F32 ) ); - syringePumpDataPublicationTimerCounter = 0; - } + syringePumpDataPublicationTimerCounter = 0; + } } - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - - -/*********************************************************************//** - * @brief - * The testSetSyringePumpDataPublishIntervalOverride function overrides the - * syringe pump data publish interval. - * @details Inputs: none - * @details Outputs: syringePumpDataPublishInterval - * @param value override syringe pump data publish interval with (in ms) - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetSyringePumpDataPublishIntervalOverride( U32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - U32 intvl = value / TASK_PRIORITY_INTERVAL; - - result = TRUE; - syringePumpDataPublishInterval.ovData = intvl; - syringePumpDataPublishInterval.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetSyringePumpDataPublishIntervalOverride function resets the override - * of the syringe pump data publish interval. - * @details Inputs: none - * @details Outputs: syringePumpDataPublishInterval - * @return TRUE if override reset successful, FALSE if not - *************************************************************************/ -BOOL testResetSyringePumpDataPublishIntervalOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - syringePumpDataPublishInterval.override = OVERRIDE_RESET; - syringePumpDataPublishInterval.ovData = syringePumpDataPublishInterval.ovInitData; - } - - return result; -} + /*********************************************************************//** * @brief + * The testSetSyringePumpDataPublishIntervalOverride function overrides the + * syringe pump data publish interval. + * @details Inputs: none + * @details Outputs: syringePumpDataPublishInterval + * @param value override syringe pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetSyringePumpDataPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + + result = TRUE; + syringePumpDataPublishInterval.ovData = intvl; + syringePumpDataPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetSyringePumpDataPublishIntervalOverride function resets the override + * of the syringe pump data publish interval. + * @details Inputs: none + * @details Outputs: syringePumpDataPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetSyringePumpDataPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + syringePumpDataPublishInterval.override = OVERRIDE_RESET; + syringePumpDataPublishInterval.ovData = syringePumpDataPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSyringePumpOperationRequest function requests a given syringe pump * operation. * @details Inputs: none @@ -2271,9 +2227,57 @@ return result; } - + /*********************************************************************//** * @brief + * The testSetHeprinBolusTargetRateOverride function overrides the + * heprine bolus target rate. + * @details Inputs: heprinBolusTargetRate + * @details Outputs: heprinBolusTargetRate + * @param: value : override heprinBolusTargetRate (in mL/hour) + * @param: value : override heprinBolusTargetRate (in mL/hour) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetHeprinBolusTargetRateOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + heparinBolusTargetRate.ovInitData = heparinBolusTargetRate.data; + heparinBolusTargetRate.ovData = value; + heparinBolusTargetRate.override = OVERRIDE_KEY; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetHeprinBolusTargetRateOverride function resets the override + * of the heprin bolus target rate. + * @details Inputs: heprinBolusTargetRate + * @details Outputs: heprinBolusTargetRate + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetHeprinBolusTargetRateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + heparinBolusTargetRate.override = OVERRIDE_RESET; + heparinBolusTargetRate.ovData = heparinBolusTargetRate.ovInitData; + heparinBolusTargetRate.ovInitData = 0.0; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSetSyringePumpStatus function overrides the syringe pump * status. * @details Inputs: none @@ -2452,4 +2456,4 @@ return result; } -/**@}*/ +/**@}*/ Index: firmware/App/Controllers/Temperatures.c =================================================================== diff -u -r3d72b777cf1ceb673d118341c46e2d6d5b7b75f5 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision 3d72b777cf1ceb673d118341c46e2d6d5b7b75f5) +++ firmware/App/Controllers/Temperatures.c (.../Temperatures.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -19,6 +19,7 @@ #include "FPGA.h" #include "InternalADC.h" +#include "NVDataMgmt.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "Temperatures.h" @@ -45,11 +46,12 @@ #define MIN_ALLOWED_TEMPERATURE 0.0 ///< Thermistors/sensors minimum allowed temperature reading. #define MAX_ALLOWED_TEMPERATURE 80.0 ///< Thermistors/sensors maximum allowed temperature reading. #define MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD ( 5 * MS_PER_SECOND ) ///< Thermistors/sensors maximum allowed temperature out of range period. +#define DATA_PUBLISH_COUNTER_START_COUNT 6 ///< Data publish counter start count. /// Temperatures exec states typedef enum thermistors_Exec_States { - TEMPERATURES_EXEC_STATE_START_STATE = 0, ///< Temperatures exec state start state. + TEMPERATURES_EXEC_STATE_WAIT_FOR_POST_STATE = 0, ///< Temperatures exec state wait for POST state. TEMPERATURES_EXEC_STATE_GET_ADC_VALUES_STATE, ///< Temperatures exec state get ADC values state. NUM_OF_TEMPERATURES_EXEC_STATES, ///< Number of temperatures exec state. } TEMPERATURES_EXEC_STATES_T; @@ -69,6 +71,8 @@ TEMPERATURES_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Temperatures publish time interval override. static U32 dataPublishCounter; ///< Temperatures data publish timer counter. static U32 adcReadCounter; ///< Temperatures ADC read counter. +static HD_TEMP_SENSORS_CAL_RECORD_T temperaturesCalRecord; ///< Temperatures calibration record. +static BOOL isPOSTComplete; ///< Temperatures POST complete flag. static const F32 THERMISTOR_VOLTAGE_CONV_COEFF = THERMISTOR_REFERENCE_VOLTAGE / (F32)TWELVE_BIT_RESOLUTION; ///< On board thermistor ADC to voltage conversion coefficient. @@ -77,31 +81,35 @@ static const F32 VENOUS_PRESS_SENSOR_TEMP_CONVERSION_COEFF = 200.0 / 2047.0; ///< Venous pressure sensor temperature conversion coefficient. static const F32 VENOUS_PRESS_SENSOR_TEMP_CONVERSION_CONSTANT = 50.0; ///< Venous pressure sensor temperature conversion constant. static const F32 ADC_BOARD_TEMP_SENSOR_CONVERSION_COEFF = 1.0 / 13584.0; ///< ADC board temperatures sensor conversion coefficient. +static const F32 ART_PRESS_SENSOR_TEMP_CONVERSION_COEFF = 200.0 / 2047.0; ///< Arterial pressure sensor temperature conversion coefficient. +static const F32 ART_PRESS_SENSOR_TEMP_CONVERSION_CONSTANT = 50.0; ///< Arterial pressure sensor temperature conversion constant. // ********** private function prototypes ********** -static TEMPERATURES_EXEC_STATES_T handleExecStart( void ); +static TEMPERATURES_EXEC_STATES_T handleExecWaitForPOST( void ); static TEMPERATURES_EXEC_STATES_T handleExecGetADCValues( void ); static void monitorTemperatures( void ); static void convertADC2Temperature( void ); -static F32 calculateThemristorTemperature( S32 adcValue ); +static F32 calculateThemristorTemperature( S32 adcValue ); static void publishTemperaturesData( void ); -static U32 getPublishTemperaturesDataInterval( void ); +static U32 getPublishTemperaturesDataInterval( void ); /*********************************************************************//** * @brief * The initTemperatures function initializes the temperatures module. * @details Inputs: none - * @details Outputs: temperaturesExecState, dataPublishCounter, temperaturesStatus + * @details Outputs: temperaturesExecState, dataPublishCounter, temperaturesStatus, + * isPOSTComplete * @return none *************************************************************************/ void initTemperatures( void ) { U08 i; - temperaturesExecState = TEMPERATURES_EXEC_STATE_START_STATE; - dataPublishCounter = 0; + temperaturesExecState = TEMPERATURES_EXEC_STATE_WAIT_FOR_POST_STATE; + dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + isPOSTComplete = FALSE; for ( i = 0; i < NUM_OF_TEMPERATURES; i++ ) { @@ -122,13 +130,22 @@ *************************************************************************/ SELF_TEST_STATUS_T execTemperaturesSelfTest( void ) { - SELF_TEST_STATUS_T status = SELF_TEST_STATUS_IN_PROGRESS; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - // TODO implement the calibration processing function. - // It returns a pass for now - status = SELF_TEST_STATUS_PASSED; + BOOL calStatus = getNVRecord2Driver( GET_CAL_TEMPERATURE_SESNORS, (U08*)&temperaturesCalRecord, sizeof( HD_TEMP_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_HD_TEMP_SENSORS, ALARM_ID_NO_ALARM ); + isPOSTComplete = TRUE; - return status; + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + } + + return result; } /*********************************************************************//** @@ -140,11 +157,18 @@ *************************************************************************/ void execTemperatures( void ) { + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + getNVRecord2Driver( GET_CAL_TEMPERATURE_SESNORS, (U08*)&temperaturesCalRecord, sizeof( HD_TEMP_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_HD_TEMP_SENSORS, ALARM_ID_NO_ALARM ); + } + // Read the sensors all the time switch ( temperaturesExecState ) { - case TEMPERATURES_EXEC_STATE_START_STATE: - temperaturesExecState = handleExecStart(); + case TEMPERATURES_EXEC_STATE_WAIT_FOR_POST_STATE: + temperaturesExecState = handleExecWaitForPOST(); break; case TEMPERATURES_EXEC_STATE_GET_ADC_VALUES_STATE: @@ -205,18 +229,18 @@ /*********************************************************************//** * @brief - * The handleExecStart function handles the start state of the exec state - * machine. + * The handleExecWaitForPOST function handles the wait for POST state of the + * exec state machine. * @details Inputs: adcReadCounter * @details Outputs: adcReadCounter * @return next state of the exec state machine *************************************************************************/ -static TEMPERATURES_EXEC_STATES_T handleExecStart( void ) +static TEMPERATURES_EXEC_STATES_T handleExecWaitForPOST( void ) { - TEMPERATURES_EXEC_STATES_T state = TEMPERATURES_EXEC_STATE_START_STATE; + TEMPERATURES_EXEC_STATES_T state = TEMPERATURES_EXEC_STATE_WAIT_FOR_POST_STATE; // Give a short time for FPGA to boot up and start sending the ADC reads - if ( ++adcReadCounter > ADC_FPGA_READ_DELAY_COUNT ) + if ( ( ++adcReadCounter > ADC_FPGA_READ_DELAY_COUNT ) && ( TRUE == isPOSTComplete ) ) { state = TEMPERATURES_EXEC_STATE_GET_ADC_VALUES_STATE; adcReadCounter = 0; @@ -247,6 +271,13 @@ temperaturesStatus[ TEMPSENSOR_VENOUS_PRESSURE_SENSOR ].rawADCRead = getFPGAVenousPressureTemperature(); temperaturesStatus[ TEMPSENSOR_PBA_ADC_SENSOR ].rawADCRead = getFPGAPBAADCTemperature(); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) +#endif + { + temperaturesStatus[ TEMPSENSOR_ARTERIAL_PRESSURE_SENSOR ].rawADCRead = getFPGADVTArterialTemperature(); + } + // Zero the counter for the next round of reading adcReadCounter = 0; } @@ -265,19 +296,29 @@ static void monitorTemperatures( void ) { TEMPERATURES_T sensor; + BOOL isTempOutOfRange = FALSE; - F32 temperature = 0.0; - U32 lastFaultSensor = 0; - F32 faultSensorTemp = 0.0; + F32 temperature = 0.0; + U32 lastFaultSensor = 0; + F32 faultSensorTemp = 0.0; for ( sensor = THERMISTOR_ONBOARD_NTC; sensor < NUM_OF_TEMPERATURES; sensor++ ) { temperature = getTemperatureValue( sensor ); + if ( ( temperature > MAX_ALLOWED_TEMPERATURE ) || ( temperature < MIN_ALLOWED_TEMPERATURE ) ) { isTempOutOfRange = TRUE; - lastFaultSensor = sensor; - faultSensorTemp = temperature; + lastFaultSensor = sensor; + faultSensorTemp = temperature; + +#ifndef _RELEASE_ + if ( ( TEMPSENSOR_ARTERIAL_PRESSURE_SENSOR == sensor ) && + ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) != SW_CONFIG_ENABLE_VALUE ) ) + { + isTempOutOfRange = FALSE; + } +#endif } } @@ -325,11 +366,38 @@ break; case TEMPSENSOR_PBA_ADC_SENSOR: - // Temperature (C) = ((ADC - 0x800000) / 13584) - 272.5 - temperature = ( ( rawADC - ADC_BOARD_TEMP_SENSOR_CONVERSION_CONST_2 ) * ADC_BOARD_TEMP_SENSOR_CONVERSION_COEFF ) - - ADC_BOARD_TEMP_SENSOR_CONVERSION_CONST_1; + +#ifndef _RELEASE_ + // If the software configuration is not enable to read the DVT arterial pressure, set the temperature to 30 to make sure + // there is no temperature error because the sensor is not available. The old arterial sensor did not have a temperature sensor + // inside it. NOTE: this line of code should be remove later. + temperature = 30.0; + + if ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + // Temperature (C) = ((ADC - 0x800000) / 13584) - 272.5 + temperature = ( ( rawADC - ADC_BOARD_TEMP_SENSOR_CONVERSION_CONST_2 ) * ADC_BOARD_TEMP_SENSOR_CONVERSION_COEFF ) - + ADC_BOARD_TEMP_SENSOR_CONVERSION_CONST_1; + } break; + case TEMPSENSOR_ARTERIAL_PRESSURE_SENSOR: + +#ifndef _RELEASE_ + // If the software configuration is not enable to read the DVT arterial pressure, set the temperature to 30 to make sure + // there is no temperature error because the sensor is not available. The old arterial sensor did not have a temperature sensor + // inside it. NOTE: this line of code should be remove later. + temperature = 30.0; + + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) +#endif + { + // Temperature (C) = ((ADC / 2047) * 200) - 50 + temperature = ( rawADC * ART_PRESS_SENSOR_TEMP_CONVERSION_COEFF ) - ART_PRESS_SENSOR_TEMP_CONVERSION_CONSTANT; + } + break; + default: // Wrong sensor was called, raise an alarm SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_TEMPERATURE_SENSOR_SELECTED, sensor ); @@ -338,7 +406,21 @@ break; } + // TODO remove this code and the if statement. This configuration is until the new arterial sensor is implemented everywhere so the temperature calibration + // structure can be updated permanently. This way the PBA sensor will be replaced with the new arterial sensor. This is to make sure the + // calibration structure does not fail in different devices with different sensors temperaturesStatus[ sensor ].temperatureValue.data = temperature; + if ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) != SW_CONFIG_ENABLE_VALUE ) + { + // Apply the calibration record the temperature values prior to updating the structures + temperaturesStatus[ sensor ].temperatureValue.data = + pow(temperature, 4) * temperaturesCalRecord.hdTemperatureSensors[ (CAL_DATA_HD_TEMEPERATURE_SENSORS_T)sensor ].fourthOrderCoeff + + pow(temperature, 3) * temperaturesCalRecord.hdTemperatureSensors[ (CAL_DATA_HD_TEMEPERATURE_SENSORS_T)sensor ].thirdOrderCoeff + + pow(temperature, 3) * temperaturesCalRecord.hdTemperatureSensors[ (CAL_DATA_HD_TEMEPERATURE_SENSORS_T)sensor ].secondOrderCoeff + + temperature * temperaturesCalRecord.hdTemperatureSensors[ (CAL_DATA_HD_TEMEPERATURE_SENSORS_T)sensor ].gain + + temperaturesCalRecord.hdTemperatureSensors[ (CAL_DATA_HD_TEMEPERATURE_SENSORS_T)sensor ].offset; + } + } } @@ -411,11 +493,12 @@ TEMPERATURES_DATA_T sensorsData; // Get all the sensors/thermistors temperature values for publication - sensorsData.onboardThermistor = getTemperatureValue( THERMISTOR_ONBOARD_NTC ); - sensorsData.powerSupply1Thermistor = getTemperatureValue( THERMISTOR_POWER_SUPPLY_1 ); - sensorsData.venousPressSensorTemp = getTemperatureValue( TEMPSENSOR_VENOUS_PRESSURE_SENSOR ); - sensorsData.fpgaBoardTempSensor = getTemperatureValue( TEMPSENSOR_FPGA_BOARD_SENSOR ); - sensorsData.pbaADCTempSensor = getTemperatureValue( TEMPSENSOR_PBA_ADC_SENSOR ); + sensorsData.onboardThermistor = getTemperatureValue( THERMISTOR_ONBOARD_NTC ); + sensorsData.powerSupply1Thermistor = getTemperatureValue( THERMISTOR_POWER_SUPPLY_1 ); + sensorsData.venousPressSensorTemp = getTemperatureValue( TEMPSENSOR_VENOUS_PRESSURE_SENSOR ); + sensorsData.fpgaBoardTempSensor = getTemperatureValue( TEMPSENSOR_FPGA_BOARD_SENSOR ); + sensorsData.pbaADCTempSensor = getTemperatureValue( TEMPSENSOR_PBA_ADC_SENSOR ); + sensorsData.arterialPressSensorTemp = getTemperatureValue( TEMPSENSOR_ARTERIAL_PRESSURE_SENSOR ); // Broadcast the temperatures data broadcastData( MSG_ID_HD_TEMPERATURES_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&sensorsData, sizeof( TEMPERATURES_DATA_T ) ); Index: firmware/App/Controllers/Temperatures.h =================================================================== diff -u -r3d72b777cf1ceb673d118341c46e2d6d5b7b75f5 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Temperatures.h (.../Temperatures.h) (revision 3d72b777cf1ceb673d118341c46e2d6d5b7b75f5) +++ firmware/App/Controllers/Temperatures.h (.../Temperatures.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -41,6 +41,7 @@ TEMPSENSOR_FPGA_BOARD_SENSOR, ///< FPGA board temperature sensor TEMPSENSOR_VENOUS_PRESSURE_SENSOR, ///< Venous pressure sensor temperature TEMPSENSOR_PBA_ADC_SENSOR, ///< PBA ADC temperature sensor + TEMPSENSOR_ARTERIAL_PRESSURE_SENSOR, ///< Arterial pressure sensor temperature NUM_OF_TEMPERATURES, ///< Number of temperatures } TEMPERATURES_T; @@ -52,6 +53,7 @@ F32 fpgaBoardTempSensor; ///< FPGA board temperature sensor F32 venousPressSensorTemp; ///< Venous pressure sensor temperature F32 pbaADCTempSensor; ///< PBA ADC temperature sensor + F32 arterialPressSensorTemp; ///< Arterial pressure sensor temperature } TEMPERATURES_DATA_T; // ********** public function prototypes ********** Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Controllers/Voltages.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Controllers/Voltages.c (.../Voltages.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/Voltages.c (.../Voltages.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/HDCommon.h =================================================================== diff -u -rd46b0f851c72959081fd4fac8e0183d0ea9666be -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision d46b0f851c72959081fd4fac8e0183d0ea9666be) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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 HDCommon.h * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Sean * @date (original) 27-Feb-2020 @@ -25,7 +25,7 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 #define HD_VERSION_MICRO 0 -#define HD_VERSION_BUILD 31 +#define HD_VERSION_BUILD 34 // ********** development build switches ********** @@ -49,7 +49,6 @@ // TODO stays as a build switch until the calibration structure is updated with the build #define SKIP_CAL_CHECK 1 // Implement software configuration - #include #include #endif Index: firmware/App/Modes/BloodPrime.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Modes/ConsumableSelfTest.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ConsumableSelfTest.c (.../ConsumableSelfTest.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/ConsumableSelfTest.c (.../ConsumableSelfTest.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r3d72b777cf1ceb673d118341c46e2d6d5b7b75f5 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 3d72b777cf1ceb673d118341c46e2d6d5b7b75f5) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -47,7 +47,7 @@ static const U32 UF_ACCURACY_CHECK_INTERVAL = ((1 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL); #define MAX_SALINE_VOLUME_DELIVERED 800 ///< Maximum saline volume delivered for a treatment. -#define SALINE_BOLUS_RATE_ML_MIN 150 ///< Fixed rate for saline bolus delivery. +#define SALINE_BOLUS_RATE_ML_MIN 300 ///< Fixed rate for saline bolus delivery. #define MAX_BOLUS_ERROR_PCT 0.2 ///< Maximum error in saline bolus volume delivered (as a percentage of target). #define MAX_ACTIVE_LOAD_CELL_CHANGE_G 50.0 ///< Maximum delta between new and previous measured UF volume. @@ -184,6 +184,8 @@ *************************************************************************/ void transitionToDialysis( void ) { + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + // Set last UF timestamp so UF ref is resumed from this time lastUFTimeStamp = getMSTimerCount(); // Send dialysate outlet pump latest UF volumes @@ -200,21 +202,25 @@ setValvePosition( VBA, VALVE_POSITION_B_OPEN ); setValvePosition( VBV, VALVE_POSITION_B_OPEN ); // Restart pumps -#ifndef RUN_PUMPS_OPEN_LOOP -#ifndef RUN_BP_OPEN_LOOP - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#else - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif -#ifndef RUN_DPI_OPEN_LOOP - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#else - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif -#else - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); -#endif + + setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); + setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); // Start Heparin pump as appropriate startHeparinPump(); @@ -286,21 +292,24 @@ // Make rate changes in real time if currently performing dialysis. if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) { -#ifndef RUN_PUMPS_OPEN_LOOP -#ifndef RUN_BP_OPEN_LOOP - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#else - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + PUMP_CONTROL_MODE_T mode = PUMP_CONTROL_MODE_CLOSED_LOOP; + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_BLOOD_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif -#ifndef RUN_DPI_OPEN_LOOP - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); -#else - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, mode ); + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DIALYSATE_INLET_PUMP_OPEN_LOOP ) ) + { + mode = PUMP_CONTROL_MODE_OPEN_LOOP; + } #endif -#else - setBloodPumpTargetFlowRate( setBloodFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); -#endif + setDialInPumpTargetFlowRate( setDialysateFlowRate, MOTOR_DIR_FORWARD, mode ); + setDialOutPumpTargetRate( setDialysateFlowRate + (S32)setUFRate, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); } } @@ -942,15 +951,14 @@ salineBolusAbortRequested = FALSE; result = SALINE_BOLUS_STATE_IDLE; } -#ifndef DISABLE_PUMP_FLOW_CHECKS // Determine if saline bolus is under/over delivering - else if ( fabs( expectedSalineBolusVolume_mL - bolusSalineVolumeDelivered_mL ) > maxBolusErrorMl ) + else if ( ( fabs( expectedSalineBolusVolume_mL - bolusSalineVolumeDelivered_mL ) > maxBolusErrorMl ) && + ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_FLOW_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) ) { activateAlarmNoData( ALARM_ID_SALINE_BOLUS_VOLUME_CHECK_FAILURE ); errorFound = TRUE; result = SALINE_BOLUS_STATE_IDLE; } -#endif } // Are we stopping the bolus? @@ -1041,9 +1049,12 @@ // Check UF rate over last hour if ( uFMeasRate > MAX_UF_RATE_ML_PER_HOUR ) { -#ifndef DISABLE_UF_ALARMS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ULTRAFILTRATION_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); + } } // Increment timer and see if time to start another 1 hour check period if ( ++uFAccuracyCheckTimerCtr >= UF_ACCURACY_CHECK_INTERVAL ) @@ -1056,9 +1067,12 @@ // Check total UF volume error if ( ( fabs( refUFVolume - measUFVolume ) ) >= (F32)MAX_UF_ACCURACY_ERROR_ML ) { -#ifndef DISABLE_UF_ALARMS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_UF_VOLUME_ACCURACY_ERROR, refUFVolume, measUFVolume ); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ULTRAFILTRATION_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_UF_VOLUME_ACCURACY_ERROR, refUFVolume, measUFVolume ); + } } } @@ -1077,17 +1091,21 @@ DG_RESERVOIR_ID_T activeRes = getDGActiveReservoir(); LOAD_CELL_ID_T loadCell = ( activeRes == DG_RESERVOIR_1 ? LOAD_CELL_RESERVOIR_1_PRIMARY : LOAD_CELL_RESERVOIR_2_PRIMARY ); F32 latestResVolume = getLoadCellWeight( loadCell ); -#ifndef DISABLE_UF_ALARMS F32 deltaVolume = latestResVolume - resLastVolume[ activeRes ]; // ensure volume change is not too excessive - indication that load cell was impacted by some kind of shock if ( fabs(deltaVolume) > MAX_ACTIVE_LOAD_CELL_CHANGE_G ) { - ALARM_ID_T deltaAlarm = ( getDGActiveReservoir() == DG_RESERVOIR_1 ? ALARM_ID_HD_LOAD_CELL_ACCELERATION_RES_1_ALARM : ALARM_ID_HD_LOAD_CELL_ACCELERATION_RES_2_ALARM ); - SET_ALARM_WITH_1_F32_DATA( deltaAlarm, deltaVolume ); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ULTRAFILTRATION_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + ALARM_ID_T deltaAlarm = ( getDGActiveReservoir() == DG_RESERVOIR_1 ? ALARM_ID_HD_LOAD_CELL_ACCELERATION_RES_1_ALARM : + ALARM_ID_HD_LOAD_CELL_ACCELERATION_RES_2_ALARM ); + SET_ALARM_WITH_1_F32_DATA( deltaAlarm, deltaVolume ); + } } else -#endif { // Calculate UF volumes and provide to dialysate outlet pump controller measUFVolume = measUFVolumeFromPriorReservoirs + ( latestResVolume - resStartVolume[ activeRes ] ); Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file ModeInitPOST.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Hung Nguyen +* @date (last) 15-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -37,6 +37,7 @@ #include "RTC.h" #include "SafetyShutdown.h" #include "SyringePump.h" +#include "system.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Temperatures.h" @@ -480,6 +481,7 @@ // Send the startup event SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_STARTUP, resetReason, systemREG1->GBLSTAT ) // log startup event w/ reset reason(s) bits SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_STARTUP, systemREG1->DEV, 0x12345678 ) // log startup event w/ device ID bits + // Send the first submode change event. It is the mode Init and it does not start from a previous // mode previous and current are both published as Init SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_OP_MODE_CHANGE, MODE_INIT, MODE_INIT ) Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file ModePreTreat.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Hung Nguyen +* @date (last) 15-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -684,7 +684,6 @@ { if ( submodeCompleteTransitionTimeCounter++ >= SUBMODE_COMPLETE_UI_TRANSITION_TIME_COUNT ) { - setOcclusionInstallLevel(); // Record occlusion pressure level after a new cartridge is installed. submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_PRIME_STATE; transitionToPrime(); Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r5e2d30dcbd02f5eb737aee7ec45c63d868daf252 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 5e2d30dcbd02f5eb737aee7ec45c63d868daf252) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file ModeTreatment.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 08-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -192,9 +192,6 @@ treatmentStartTimeStamp = getRTCTimestamp(); treatmentEndTimeStamp = 0; - initBloodFlow(); - initDialInFlow(); - initDialOutFlow(); } /*********************************************************************//** Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -rb1738d6bf41a8cc4924ba36a5a7d1abc60a3b1d8 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision b1738d6bf41a8cc4924ba36a5a7d1abc60a3b1d8) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeTreatmentParams.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Sean Nash * @date (original) 29-May-2020 @@ -921,6 +921,7 @@ return ( ( origTreatmentParams.uFVolume_L * ML_PER_LITER ) / origTreatmentParams.treatmentDuration_min ); } + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -959,7 +960,76 @@ } } } + return result; +} +/*********************************************************************//** + * @brief + * The testUpdateCurrentTreatmentParameters function pulls the current + * treatment parameters from the critical section if data has been + * determined to be valid. Calls sendTestCurrentTreatmentParametersResponse. + * @details Inputs: none + * @details Outputs: CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T containing + * treatment parameters. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSendCurrentTreatmentParameters( void ) +{ + BOOL result = FALSE; + CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T current_treatment_params; + + if ( TRUE == isTestingActivated() ) + { + // Test one parameter for set since all parameters are set after parameter validation. + if(TRUE == isCriticalDataSet( &treatmentParameters[TREATMENT_PARAM_BLOOD_FLOW] )) + { + result = TRUE; + current_treatment_params.accepted = TRUE; + current_treatment_params.treatment_parameters.bloodFlowRate_mL_min = getTreatmentParameterU32(TREATMENT_PARAM_BLOOD_FLOW); + current_treatment_params.treatment_parameters.dialysateFlowRate_mL_min = getTreatmentParameterU32(TREATMENT_PARAM_DIALYSATE_FLOW); + current_treatment_params.treatment_parameters.treatmentDuration_min = getTreatmentParameterU32(TREATMENT_PARAM_TREATMENT_DURATION); + current_treatment_params.treatment_parameters.heparinPreStop_min = getTreatmentParameterU32(TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME); + current_treatment_params.treatment_parameters.salineBolusVolume_mL = getTreatmentParameterU32(TREATMENT_PARAM_SALINE_BOLUS_VOLUME); + current_treatment_params.treatment_parameters.acidConcentrate = getTreatmentParameterU32(TREATMENT_PARAM_ACID_CONCENTRATE); + current_treatment_params.treatment_parameters.bicarbConcentrate = getTreatmentParameterU32(TREATMENT_PARAM_BICARB_CONCENTRATE); + current_treatment_params.treatment_parameters.dialyzerType = getTreatmentParameterU32(TREATMENT_PARAM_DIALYZER_TYPE); + current_treatment_params.treatment_parameters.heparinType = getTreatmentParameterU32(TREATMENT_PARAM_HEPARIN_TYPE); + current_treatment_params.treatment_parameters.bloodPressureMeasurementInterval_min = getTreatmentParameterU32(TREATMENT_PARAM_BP_MEAS_INTERVAL); + current_treatment_params.treatment_parameters.rinsebackFlowRate_mL_min = getTreatmentParameterU32(TREATMENT_PARAM_RINSEBACK_FLOW_RATE); + current_treatment_params.treatment_parameters.arterialPressureLowLimit_mmHg = getTreatmentParameterS32(TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT); + current_treatment_params.treatment_parameters.arterialPressureHighLimit_mmHg = getTreatmentParameterS32(TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT); + current_treatment_params.treatment_parameters.venousPressureLowLimit_mmHg = getTreatmentParameterS32(TREATMENT_PARAM_VEN_PRESSURE_LOW_LIMIT); + current_treatment_params.treatment_parameters.venousPressureHighLimit_mmHg = getTreatmentParameterS32(TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT); + current_treatment_params.treatment_parameters.heparinDispenseRate_mL_hr = getTreatmentParameterF32(TREATMENT_PARAM_HEPARIN_DISPENSE_RATE); + current_treatment_params.treatment_parameters.heparinBolusVolume_mL = getTreatmentParameterF32(TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME); + current_treatment_params.treatment_parameters.dialysateTemperature_degC = getTreatmentParameterF32(TREATMENT_PARAM_DIALYSATE_TEMPERATURE); + current_treatment_params.uFVolume_L = getTreatmentParameterF32(TREATMENT_PARAM_UF_VOLUME); + } + else + { + current_treatment_params.accepted = FALSE; + current_treatment_params.treatment_parameters.bloodFlowRate_mL_min = 0; + current_treatment_params.treatment_parameters.dialysateFlowRate_mL_min = 0; + current_treatment_params.treatment_parameters.treatmentDuration_min = 0; + current_treatment_params.treatment_parameters.heparinPreStop_min = 0; + current_treatment_params.treatment_parameters.salineBolusVolume_mL = 0; + current_treatment_params.treatment_parameters.acidConcentrate = 0; + current_treatment_params.treatment_parameters.bicarbConcentrate = 0; + current_treatment_params.treatment_parameters.dialyzerType = 0; + current_treatment_params.treatment_parameters.heparinType = 0; + current_treatment_params.treatment_parameters.bloodPressureMeasurementInterval_min = 0; + current_treatment_params.treatment_parameters.rinsebackFlowRate_mL_min = 0; + current_treatment_params.treatment_parameters.arterialPressureLowLimit_mmHg = 0; + current_treatment_params.treatment_parameters.arterialPressureHighLimit_mmHg = 0; + current_treatment_params.treatment_parameters.venousPressureLowLimit_mmHg = 0; + current_treatment_params.treatment_parameters.venousPressureHighLimit_mmHg = 0; + current_treatment_params.treatment_parameters.heparinDispenseRate_mL_hr = 0; + current_treatment_params.treatment_parameters.heparinBolusVolume_mL = 0; + current_treatment_params.treatment_parameters.dialysateTemperature_degC = 0; + current_treatment_params.uFVolume_L = 0; + } + sendTestCurrentTreatmentParametersResponse(current_treatment_params); + } return result; } Index: firmware/App/Modes/ModeTreatmentParams.h =================================================================== diff -u -rcf0f5e54c1a7af4d8a739cbd677d899d95e4019b -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision cf0f5e54c1a7af4d8a739cbd677d899d95e4019b) +++ firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeTreatmentParams.h * -* @author (last) Behrouz NematiPour -* @date (last) 09-Dec-2021 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Sean Nash * @date (original) 29-May-2020 @@ -72,6 +72,17 @@ F32 uFVolume_L; ///< Original ultrafiltration volume (in L) set by user before treatment start } ADJ_TREATMENT_PARAMS_T; + +/// Record structure for current treatment parameters +typedef struct +{ + U32 accepted; ///< Accepted or rejected based on if critical data has been set. + TREATMENT_PARAMS_DATA_PAYLOAD_T treatment_parameters; ///< Record structure of treatment parameters + F32 uFVolume_L; ///< Current ultrafiltration volume (in L). + +} CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T; + + // ********** Public function prototypes ********** void initTreatParamsMode( void ); // Initialize this module @@ -99,6 +110,7 @@ F32 getUltrafiltrationRateOriginal( void ); // Get/calculate the original ultrafiltration rate, by ultrafiltration volume and treatment duration set in pre-treatment mode by user. BOOL testSetTreatmentParameter( TREATMENT_PARAM_T param, CRITICAL_DATAS_T value ); // Set a specific treatment parameter value +BOOL testSendCurrentTreatmentParameters(); // Update current treatment parameters /**@}*/ Index: firmware/App/Modes/Prime.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Modes/Prime.h =================================================================== diff -u -rb03a3ed91ebe15cfb419e34018f8fe600e744b4b -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/Prime.h (.../Prime.h) (revision b03a3ed91ebe15cfb419e34018f8fe600e744b4b) +++ firmware/App/Modes/Prime.h (.../Prime.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2022 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. Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Modes/SampleWater.c =================================================================== diff -u -r667feab319b14681a0330a715da7a1ba930b518d -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/SampleWater.c (.../SampleWater.c) (revision 667feab319b14681a0330a715da7a1ba930b518d) +++ firmware/App/Modes/SampleWater.c (.../SampleWater.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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. Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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 SelfTests.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Hung Nguyen +* @date (last) 15-Feb-2022 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -41,6 +41,7 @@ #define PUMP_RUN_SELF_TEST_TIME_MS ( 15 * MS_PER_SECOND ) ///< Self-test time to run pumps in ms. #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. +#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 3 * MS_PER_SECOND ) ///< Delay 3 seconds then check for syringe pump prime occlusion. #define BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 5 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. #define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. @@ -62,8 +63,9 @@ #define WET_SELF_TEST_DISPLACEMENT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms. #define RESERVOIR_SETTLE_TIME_MS ( 4 * MS_PER_SECOND ) ///< Time allotted for reservoir to settle in ms. -#define MAX_NO_CARTRIDGE_SELF_TEST_TIME 30 ///< Maximum no cartridge self-test time (in seconds). +#define MAX_NO_CARTRIDGE_SELF_TEST_TIME 30 ///< Maximum no cartridge self-test time (in seconds). #define MAX_DRY_SELF_TEST_TIME ( 3 * SEC_PER_MIN ) ///< Maximum dry self-test time (in seconds). +#define CARTRIDGE_INSERT_PRESSURE_SETTLE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Time (in ms) required to wait for occlusion pressure to settle after cartridge insertion. #define SELF_TEST_TIME_DATA_PUB_INTERVAL ( MS_PER_SECOND ) ///< Interval (ms/task time) at which self-test time data is published on the CAN bus. @@ -112,6 +114,7 @@ static U32 selfTestStartTime; ///< Starting time of self-test (in ms). static U32 selfTestPreviousPublishDataTime; ///< Last time self-test time data is being published (in ms). +static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. static BOOL useHeparin; ///< Flag indicates the user of heparin. @@ -135,6 +138,7 @@ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( SELF_TEST_STATUS_T *result ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( SELF_TEST_STATUS_T *result ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpPrimeState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ); @@ -161,6 +165,7 @@ { selfTestStartTime = 0; selfTestPreviousPublishDataTime = 0; + syringeOcclusionDelayStartTime = 0; } /*********************************************************************//** @@ -201,7 +206,16 @@ signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); - stopSyringePump(); + + if ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) + { + retractSyringePump(); + } + else + { + stopSyringePump(); + } + setValvePosition( VDI, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VDO, VALVE_POSITION_A_INSERT_EJECT ); setValvePosition( VBA, VALVE_POSITION_A_INSERT_EJECT ); @@ -429,6 +443,10 @@ currentDrySelfTestsState = handleDrySelfTestSyringePumpPrimeState(); break; + case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE: + currentDrySelfTestsState = handleDrySelfTestSyringePumpOcclusionDetectionState(); + break; + case DRY_SELF_TESTS_STOPPED_STATE: currentDrySelfTestsState = handleDrySelfTestStoppedState(); break; @@ -1022,6 +1040,33 @@ /*********************************************************************//** * @brief + * The handleDrySelfTestSyringePumpOcclusionDetectionState function handles + * occlusion detection after prime has completed. + * @details Inputs: none + * @details Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; + + if ( TRUE == didTimeout( syringeOcclusionDelayStartTime, SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ) ) + { + checkForPrimeOcclusion(); + state = DRY_SELF_TESTS_COMPLETE_STATE; + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleDrySelfTestStoppedState function handles the stopped dry self-tests * operation. * @details Inputs: none @@ -1090,8 +1135,16 @@ if ( FALSE == cmdResp.rejected ) { + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SETUP_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); fmdIntegratedVolume = 0.0; + + if ( ( bolusVol > 0.0 ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) + { + startHeparinBolus(); // moved here from startHeparinPump() in Dialysis.c + } + state = WET_SELF_TESTS_SETUP_STATE; } } Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rcf0f5e54c1a7af4d8a739cbd677d899d95e4019b -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision cf0f5e54c1a7af4d8a739cbd677d899d95e4019b) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2022 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 AlarmMgmtSWFaults.h * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Hung Nguyen +* @date (last) 15-Feb-2022 * * @author (original) Quang Nguyen * @date (original) 20-May-2021 @@ -166,6 +166,7 @@ SW_FAULT_ID_INVALID_TREATMENT_RESERVOIR_MANAGEMENT_STATE, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_S32_PARAM_MIN_LIMIT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_GET_S32_PARAM_MAX_LIMIT, + SW_FAULT_ID_ILLEGAL_MEM_ACCESS, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file SystemComm.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -1612,8 +1612,15 @@ case MSG_ID_HD_FAN_RPM_ALARM_START_TIME_OFFSET_OVERRIDE: handleTestFansRPMAlarmStartTimeOffsetOverrideRequest( message ); + + case MSG_ID_HD_SYRINGE_PUMP_HEPRIN_BOLUS_TARGET_RATE_OVERRIDE: + handleTestSyringePumpHeprinBolusTargetRateOverrideRequest( message ); break; + case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: + handleTestCurrentTreamtmentParametersRequest( message ); + break; + case MSG_ID_HD_FANS_DUTY_CYCLE_OVERRIDE: handleSetFansDutyCycleOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.c * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -2715,6 +2715,8 @@ return result; } + + /*********************************************************************//** * @brief * The handleChangeUFSettingsRequest function handles a ultrafiltration @@ -5604,6 +5606,38 @@ } /*********************************************************************//** + * @brief + * The handleTestSyringePumpHeprinBolusTargetRateOverrideRequest function handles a + * request to override the syringe pump heprin bolus target rate. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestSyringePumpHeprinBolusTargetRateOverrideRequest( 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 = testSetHeprinBolusTargetRateOverride( payload.state.f32 ); + } + else + { + result = testResetHeprinBolusTargetRateOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** * @brief * The handleSetHDSystemRecord function handles a request to set the HD * system data record. @@ -6921,4 +6955,48 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The handleTestCurrentTreamtmentParametersRequest function handles a + * request to retrieve the current treatment parameters. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestCurrentTreamtmentParametersRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + result = TRUE; + // ACK request + result = testSendCurrentTreatmentParameters(); + } + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The sendTestCurrentTreatmentParametersResponse function constructs a current + * treatment parameter response message to the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: current treatment prameters response msg constructed and queued. + * @param data response data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendTestCurrentTreatmentParametersResponse(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T current_params) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RES_CURRENT_TREATMENT_PARAMETERS; + msg.hdr.payloadLen = sizeof(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T); + memcpy(payloadPtr, ¤t_params, sizeof(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T)); + + return serializeMessage(msg, COMM_BUFFER_OUT_CAN_PC, ACK_REQUIRED ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r687dc2717d2f6b128b73526791f08d7176e447e8 -rf6b78d1fe6741043de38707211710ab0e8a08483 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 687dc2717d2f6b128b73526791f08d7176e447e8) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision f6b78d1fe6741043de38707211710ab0e8a08483) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.h * -* @author (last) Dara Navaei -* @date (last) 04-Jan-2022 +* @author (last) Michael Garthwaite +* @date (last) 18-Feb-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -37,6 +37,7 @@ #include "ModePreTreat.h" #include "ModeStandby.h" #include "ModeTreatment.h" +#include "ModeTreatmentParams.h" #include "MsgQueues.h" #include "NVDataMgmt.h" #include "PresOccl.h" @@ -662,6 +663,9 @@ // MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE: void handleTestSyringePumpMeasuredRateOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_SYRINGE_PUMP_HEPRIN_BOLUS_TARGET_RATE_OVERRIDE: +void handleTestSyringePumpHeprinBolusTargetRateOverrideRequest( MESSAGE_T *message ); + // MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE: void handleTestSyringePumpMeasuredForceOverrideRequest( MESSAGE_T *message ); @@ -773,9 +777,16 @@ // MSG_ID_HD_FAN_RPM_ALARM_START_TIME_OVERRIDE void handleTestFansRPMAlarmStartTimeOffsetOverrideRequest( MESSAGE_T *message ); + // MSG_ID_HD_FANS_DUTY_CYCLE_OVERRIDE void handleSetFansDutyCycleOverrideRequest( MESSAGE_T *message ); +// MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS +void handleTestCurrentTreamtmentParametersRequest( MESSAGE_T *message ); + +// MSG_ID_HD_RES_CURRENT_TREATMENT_PARAMETERS +BOOL sendTestCurrentTreatmentParametersResponse(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T current_params); + /**@}*/ #endif