Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r685e17a553a4fdf7dd8b3715e95d151eeff3c866 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 685e17a553a4fdf7dd8b3715e95d151eeff3c866) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -15,7 +15,7 @@ * ***************************************************************************/ -#include +#include // Used for fabs() and pow() functions #include "can.h" #include "etpwm.h" @@ -93,7 +93,7 @@ #define BP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000238 ///< ~42 BP motor RPM = 1% PWM duty cycle #define BP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< Conversion factor from ADC counts to mA for blood pump motor -#define BP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter +#define BP_REV_PER_LITER 144.7 ///< Rotor revolutions per liter #define BP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( BP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to motor RPM. #define BP_GEAR_RATIO 32.0 ///< Blood pump motor to blood pump gear ratio #define BP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed @@ -124,6 +124,20 @@ #define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x07 ///< Blood flow meter NVM parameter status. #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. + +#ifdef ENABLE_ALTERNATE_FLOW +#define BLOOD_PC2 -0.0000090267 ///< Pressure compensation coefficient (2nd order) for blood pump. +#define BLOOD_PC1 -0.00071147 ///< Pressure compensation coefficient (1st order) for blood pump. +#define BLOOD_NSV 3.4555 ///< Nominal stroke (1/2 rotor revolution) volume (in mL) for blood pump. +#define BLOOD_SC2 -0.0000000718 ///< Speed compensation coefficient (2nd order) for blood pump. +#define BLOOD_SC1 0.0000851 ///< Speed compensation coefficient (1st order) for blood pump. +#define BLOOD_SC0 -0.027 ///< Speed compensation coefficient (offset) for blood pump. +#define BLOOD_PSC2 -0.00000382 ///< Additional pressure compensation coefficient (2nd order) for blood pump. +#define BLOOD_PSC1 0.000197 ///< Additional pressure compensation coefficient (1st order) for blood pump. +#define BLOOD_PSC0 0.17 ///< Additional pressure compensation coefficient (offset) for blood pump. +#define BLOOD_TS0 1000.0 ///< Lower boundary of weighted speed transition (in RPM). +#define BLOOD_TS1 1500.0 ///< Upper boundary of weighted speed transition (in RPM). +#endif /// Enumeration of blood pump controller states. typedef enum BloodPump_States @@ -167,13 +181,23 @@ /// Interval (in task intervals) at which to publish blood flow data to CAN bus. static OVERRIDE_U32_T bloodFlowDataPublishInterval = { BLOOD_FLOW_DATA_PUB_INTERVAL, BLOOD_FLOW_DATA_PUB_INTERVAL, BLOOD_FLOW_DATA_PUB_INTERVAL, 0 }; -static S32 targetBloodFlowRate = 0; ///< Requested blood flow rate -static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow rate -static OVERRIDE_F32_T bloodPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump rotor speed -static OVERRIDE_F32_T bloodPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor speed -static OVERRIDE_F32_T adcBloodPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller speed -static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current -static OVERRIDE_F32_T bloodFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow signal strength (%) +static S32 targetBloodFlowRate = 0; ///< Requested blood flow rate. +static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow rate. +static OVERRIDE_F32_T bloodPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump rotor speed. +static OVERRIDE_F32_T bloodPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor speed. +static OVERRIDE_F32_T adcBloodPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller speed. +static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current. +static OVERRIDE_F32_T bloodFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow signal strength (%). +#ifdef ENABLE_ALTERNATE_FLOW + static F32 calcBloodFlowRate = 0.0; ///< Calculated blood flow rate from pump speed and upstream pressure. + + static F32 bloodPCSV; ///< Calculated pressure corrected blood pump stroke volume. + static F32 bloodSCSV; ///< Calculated speed corrected blood pump stroke volume. + static F32 bloodPSCSV; ///< Calculated additional pressure corrected blood pump stroke volume. + static F32 bloodHSWF; ///< High speed weighting factor for blood pump stroke volume calculation. + static F32 bloodLSWF; ///< Low speed weighting factor for blood pump stroke volume calculation. + static F32 bloodPSCSVT; ///< Pressure corrected, speed corrected blood pump stroke volume with weighted transition. +#endif static U32 bpControlTimerCounter = 0; ///< Determines when to perform control on blood flow @@ -195,7 +219,9 @@ static U08 lastBloodFlowFastPacketReadCtr = 0; ///< Previous read counter for the blood flow fast packets. static U08 lastBloodFlowSlowPacketReadCtr = 0; ///< Previous read counter for the blood flow slow packets. static U08 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. +#ifndef DISABLE_PUMP_FLOW_CHECKS static U08 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. +#endif static HD_FLOW_SENSORS_CAL_RECORD_T bloodFlowCalRecord; ///< Blood flow sensor calibration record. // ********** private function prototypes ********** @@ -219,6 +245,38 @@ static void checkBloodPumpMCCurrent( void ); static void checkBloodFlowSensorSignalStrength( void ); static BOOL processCalibrationData( void ); +#ifdef ENABLE_ALTERNATE_FLOW +static void calcBloodFlow( void ); + +/*********************************************************************//** + * @brief + * The calcBloodFlow function calculates an estimated blood flow rate from + * blood pump speed and arterial pressure. + * @details Inputs: BP set speed, arterial pressure + * @details Outputs: calcBloodFlowRate + * @return none + *************************************************************************/ +static void calcBloodFlow( void ) +{ + F32 artPres = getLongFilteredArterialPressure(); + F32 artPres_2 = pow( artPres, 2.0 ); + F32 motSpd = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); // TODO - should we use measured speed? getMeasuredBloodPumpSpeed() + F32 motSpd_2 = pow( motSpd, 2.0 ); + F32 rotSpd = motSpd / BP_GEAR_RATIO; + F32 strokeSpd = rotSpd * 2.0; // 1 rotor revolution = 2 strokes + + // Calculate compensated stroke volume (in mL). + bloodPCSV = BLOOD_PC2 * artPres_2 + BLOOD_PC1 * artPres + BLOOD_NSV; + bloodSCSV = bloodPCSV * ( 1.0 + BLOOD_SC2 * motSpd_2 + BLOOD_SC1 * motSpd + BLOOD_SC0 ); + bloodPSCSV = bloodSCSV * ( 1.0 + BLOOD_PSC2 * artPres_2 + BLOOD_PSC1 * artPres + BLOOD_PSC0 ); + bloodHSWF = ( ( motSpd - BLOOD_TS0 > 0.0 ? motSpd - BLOOD_TS0 : 0.0 ) - ( motSpd - BLOOD_TS1 > 0.0 ? motSpd - BLOOD_TS1 : 0.0 ) ) / ( BLOOD_TS1 - BLOOD_TS0 ); + bloodLSWF = 1.0 - bloodHSWF; + bloodPSCSVT = bloodLSWF * bloodPCSV + bloodHSWF * bloodPSCSV; + + // Blood flow = stroke speed (strokes/min) x stroke volume (mL/stroke) = mL/min + calcBloodFlowRate = strokeSpd * bloodPSCSVT; +} +#endif /*********************************************************************//** * @brief @@ -526,6 +584,10 @@ checkBloodFlowSensorSignalStrength(); } +#ifdef ENABLE_ALTERNATE_FLOW + calcBloodFlow(); +#endif + // Publish blood flow data on interval publishBloodFlowData(); } @@ -913,7 +975,11 @@ payload.measRotorSpd = getMeasuredBloodPumpRotorSpeed(); payload.measPumpSpd = getMeasuredBloodPumpSpeed(); payload.measMCSpd = getMeasuredBloodPumpMCSpeed(); +#ifdef ENABLE_ALTERNATE_FLOW + payload.measMCCurr = calcBloodFlowRate; +#else payload.measMCCurr = getMeasuredBloodPumpMCCurrent(); +#endif payload.pwmDC = bloodPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; payload.flowSigStrength = getMeasuredBloodFlowSignalStrength() * FRACTION_TO_PERCENT_FACTOR; broadcastBloodFlowData( &payload ); Index: firmware/App/Controllers/Buttons.c =================================================================== diff -u -r8c00197ce69e80f1967aa3f2eb36beb3573f36f3 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 8c00197ce69e80f1967aa3f2eb36beb3573f36f3) +++ firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -348,6 +348,24 @@ } return result; +} + +/*********************************************************************//** + * @brief + * The initiatePowerOff function initiates a power off sequence. + * @details Inputs: none + * @details Outputs: offRequestDelayTimer, offRequestPulseTimer, offRequestPulseCount, offButtonPressPending + * @return none + *************************************************************************/ +void initiatePowerOff( void ) +{ + // Warn NV Data Mgr that power will be lost shortly + signalPowerOffWarning(); + // Mimic confirmed power off button state to initiate power off cycle + offRequestDelayTimer = 0; + offRequestPulseTimer = 0; + offRequestPulseCount = OFF_REQUEST_PULSE_COUNT; + offButtonPressPending = TRUE; } /*********************************************************************//** Index: firmware/App/Controllers/Buttons.h =================================================================== diff -u -r0b3a29a3a189b9d357d3eaa554c7baf22de30e81 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/Buttons.h (.../Buttons.h) (revision 0b3a29a3a189b9d357d3eaa554c7baf22de30e81) +++ firmware/App/Controllers/Buttons.h (.../Buttons.h) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -55,7 +55,9 @@ SELF_TEST_STATUS_T execStuckButtonTest( void ); BUTTON_STATE_T getOffButtonState( void ); -BUTTON_STATE_T getStopButtonState( void ); +BUTTON_STATE_T getStopButtonState( void ); + +void initiatePowerOff( void ); BOOL testSetOffButtonStateOverride( U32 value ); BOOL testResetOffButtonStateOverride( void ); Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -re64816def7cd98e7dcb6d133b3a56c9fea835af3 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision e64816def7cd98e7dcb6d133b3a56c9fea835af3) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -91,7 +91,7 @@ #define DIP_MOTOR_RPM_TO_PWM_DC_FACTOR 0.000193 ///< ~52 BP motor RPM = 1% PWM duty cycle #define DIP_CURRENT_ADC_TO_MA_FACTOR 3.002 ///< Conversion factor from ADC counts to mA for dialIn pump motor. -#define DIP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter. +#define DIP_REV_PER_LITER 144.7 ///< Rotor revolutions per liter. /// Macro converts flow rate to motor RPM. #define DIP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DIP_REV_PER_LITER / ML_PER_LITER ) #define DIP_GEAR_RATIO 32.0 ///< DialIn pump motor to dialIn pump gear ratio. @@ -201,7 +201,9 @@ static U08 lastDialysateFlowFastPacketReadCtr = 0; ///< Previous read counter for the dialysate flow fast packets. static U08 lastDialysateFlowSlowPacketReadCtr = 0; ///< Previous read counter for the dialysate flow slow packets. static U08 lastDialInPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. +#ifndef DISABLE_PUMP_FLOW_CHECKS static U08 lastDialysateFlowCommErrorCount = 0; ///< Previous DPi flow sensor comm error count. +#endif static HD_FLOW_SENSORS_CAL_RECORD_T dialysateFlowCalRecord; ///< Dialysate flow sensor calibration record. // ********** private function prototypes ********** @@ -493,8 +495,8 @@ checkDialInPumpRotor(); // Check flow sensor signal strength checkDialInFlowSensorSignalStrength(); - } - + } + // Publish dialIn flow data on interval publishDialInFlowData(); } Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -re64816def7cd98e7dcb6d133b3a56c9fea835af3 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision e64816def7cd98e7dcb6d133b3a56c9fea835af3) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -93,7 +93,7 @@ /*** setDialOutFlowRxTotalVolumeAndRxTime ***/ -#define DOP_REV_PER_LITER 150.0 ///< Rotor revolutions per liter. +#define DOP_REV_PER_LITER 144.7 ///< Rotor revolutions per liter. #define DOP_ML_PER_MIN_TO_PUMP_RPM_FACTOR ( DOP_REV_PER_LITER / ML_PER_LITER ) ///< Conversion factor from mL/min to pump motor RPM. #define DOP_GEAR_RATIO 32.0 ///< Pump motor to pump gear ratio. #define DOP_PWM_ZERO_OFFSET 0.1 ///< 10% PWM duty cycle = zero speed. Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r38a89cb53b4ed2e467f51d41e30d43010fdd23e3 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 38a89cb53b4ed2e467f51d41e30d43010fdd23e3) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -118,20 +118,24 @@ 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. static U32 dialInPumpOcclusionAfterCartridgeInstall; ///< Measured dialysate inlet pump occlusion reading taken after cartridge install. static U32 dialOutPumpOcclusionAfterCartridgeInstall; ///< Measured dialysate outlet 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 lastDPiOcclReadCtr; ///< Previous DPi occlusion sensor read count. static U08 lastDPoOcclReadCtr; ///< Previous DPo occlusion sensor read count. static U08 lastBPErrorCtr; ///< Previous BP error count. static U08 lastDPIErrorCtr; ///< Previous DPi error count. static U08 lastDPOErrorCtr; ///< Previous DPo 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. @@ -190,20 +194,24 @@ lastArterialPressureReadCtr = 0; lastVenousPressureReadCtr = 0; +#ifndef DISABLE_PRESSURE_CHECKS lastBPOcclReadCtr = 0; lastDPiOcclReadCtr = 0; lastDPoOcclReadCtr = 0; lastBPErrorCtr = 0; lastDPIErrorCtr = 0; lastDPOErrorCtr = 0; +#endif longFilteredArterialPressure = 0.0; shortFilteredArterialPressure = 0.0; shortFilteredVenousPressure = 0.0; +#ifndef DISABLE_PRESSURE_CHECKS bloodPumpOcclusionAfterCartridgeInstall = 0; dialInPumpOcclusionAfterCartridgeInstall = 0; dialOutPumpOcclusionAfterCartridgeInstall = 0; +#endif } /*********************************************************************//** @@ -287,9 +295,11 @@ *************************************************************************/ void setOcclusionInstallLevels( void ) { +#ifndef DISABLE_PRESSURE_CHECKS bloodPumpOcclusionAfterCartridgeInstall = getMeasuredBloodPumpOcclusion(); dialInPumpOcclusionAfterCartridgeInstall = getMeasuredDialInPumpOcclusion(); dialOutPumpOcclusionAfterCartridgeInstall = getMeasuredDialOutPumpOcclusion(); +#endif } /*********************************************************************//** @@ -478,13 +488,15 @@ dialInPumpOcclusion.data = (U32)getFPGADialInPumpOcclusion(); dialOutPumpOcclusion.data = (U32)getFPGADialOutPumpOcclusion(); +#ifndef DISABLE_PRESSURE_CHECKS // Record occlusion read and error counters for next time around lastBPOcclReadCtr = bpReadCtr; lastDPiOcclReadCtr = dpiReadCtr; lastDPoOcclReadCtr = dpoReadCtr; lastBPErrorCtr = bpErrorCtr; lastDPIErrorCtr = dpiErrorCtr; lastDPOErrorCtr = dpoErrorCtr; +#endif } /*********************************************************************//** Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r8466e63f95f65a3ffb18c3af85ac99328e41167b -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -196,8 +196,10 @@ static S32 syringePumpLastPositions[ SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN ]; ///< Last encoder positions for the syringe pump. static U32 syringePumpMotorSpeedCalcIdx; ///< Index into 1 second buffer of syringe pump encoder positions. static U32 syringePumpSpeedCalcTimerCounter; ///< Used to calculate measured rate from change in position over time. +#ifndef DISABLE_SYRINGE_PUMP_ALARMS static MOTOR_DIR_T syringePumpControllerMeasuredDirection; ///< Measured direction of syringe pump per controller. static MOTOR_DIR_T syringePumpEncoderMeasuredDirection; ///< Measured direction of syringe pump per encoder position relative to previous. +#endif static BOOL syringePumpRetractRequested; ///< Flag indicates a retract operation is requested. static BOOL syringePumpSeekRequested; ///< Flag indicates a plunger seek operation is requested. @@ -275,8 +277,10 @@ syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpLastPosition = 0; +#ifndef DISABLE_SYRINGE_PUMP_ALARMS syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; +#endif syringePumpDataPublicationTimerCounter = 0; syringePumpSpeedCalcTimerCounter = 0; @@ -965,10 +969,12 @@ calcSafetyVolumeDelivered(); // Calculate measured rate (mL/hr) calcMeasRate(); +#ifndef DISABLE_SYRINGE_PUMP_ALARMS // Get measured direction syringePumpControllerMeasuredDirection = ( ( getSyringePumpEncoderStatus() & SYRINGE_PUMP_ENCODER_DIRECTION_BIT ) != 0 ? MOTOR_DIR_REVERSE : MOTOR_DIR_FORWARD ); // Calculate direction from encoder position relative to last syringePumpEncoderMeasuredDirection = ( getSyringePumpPosition() - syringePumpLastPosition >= 0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); +#endif // Check if syringe pump is on while BP is off { @@ -1619,13 +1625,13 @@ static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ) { BOOL result = stopPump; +#ifndef DISABLE_SYRINGE_PUMP_ALARMS F32 rate = getSyringePumpMeasRate(); F32 max = MAX( rate, syringePumpSetRate ); F32 min = MIN( rate, syringePumpSetRate ); - F32 delta = max - min; F32 error = ( max > 0.0 ? ( 1.0 - fabs( min / max ) ) : 0.0 ); + F32 delta = max - min; -#ifndef DISABLE_SYRINGE_PUMP_ALARMS // Alarm on rate if off by more than 5% or 0.1 mL/hr, whichever is greater if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, ( ( error > pctMargin ) && ( delta > SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR ) ) ) ) { Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r124b3745d056ac667280cfa0ae1fab8610d44ed2 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 124b3745d056ac667280cfa0ae1fab8610d44ed2) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -330,7 +330,7 @@ // Valve not in position cannot be requested // All the other positions are valid - if ( position != VALVE_POSITION_NOT_IN_POSITION && valve < NUM_OF_VALVES ) + if ( ( position < NUM_OF_VALVE_POSITIONS ) && ( position != VALVE_POSITION_NOT_IN_POSITION ) && ( valve < NUM_OF_VALVES ) ) { valvesStatus[ valve ].commandedPosition = position; valvesStatus[ valve ].hasTransitionBeenRequested = TRUE; @@ -874,8 +874,6 @@ if ( isAlarmActive( ALARM_ID_HD_VALVE_TRANSITION_TIMEOUT ) && valvesStatus[ valve ].commandedPosition == VALVE_POSITION_C_CLOSE ) { activateSafetyShutdown(); - // Set the alarm - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_VALVE_TRANSITION_TIMEOUT, (U32)valve ); } } // Check if the valve is close to the temporary target position and if it is, assign the next target position Index: firmware/App/Controllers/Voltages.h =================================================================== diff -u -r40b37059da0ecd27dc9beb48614f6f3869d18732 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Controllers/Voltages.h (.../Voltages.h) (revision 40b37059da0ecd27dc9beb48614f6f3869d18732) +++ firmware/App/Controllers/Voltages.h (.../Voltages.h) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -64,6 +64,8 @@ F32 fpgaVpvn; ///< FPGA pvn voltage } VOLTAGES_DATA_PAYLOAD_T; +#define MIN_24V_MEASURED_FOR_AC 20.0 ///< Minimum voltage from 24V in order to say we have AC power. + // ********** public function prototypes ********** void initVoltagesMonitor( void ); Index: firmware/App/HDCommon.h =================================================================== diff -u -ra64f4bd62ca1b6065cd8946f5130674e578bc2d7 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/HDCommon.h (.../HDCommon.h) (revision a64f4bd62ca1b6065cd8946f5130674e578bc2d7) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -24,8 +24,8 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 -#define HD_VERSION_MICRO 5 -#define HD_VERSION_BUILD 20 +#define HD_VERSION_MICRO 0 +#define HD_VERSION_BUILD 0 // ********** development build switches ********** @@ -37,26 +37,26 @@ // #define RUN_WITHOUT_DG 1 // Run HD w/o DG // #define SIMULATE_UI 1 // Build w/o requirement that UI be there // #define TASK_TIMING_OUTPUT_ENABLED 1 // Re-purposes alarm lamp pins for task timing -// #define DISABLE_ALARM_AUDIO 1 // Disable alarm audio + #define DISABLE_ALARM_AUDIO 1 // Disable alarm audio // #define SKIP_POST 1 // Skip POST tests - all pass // #define DONT_SKIP_NV_POST 1 // Do not skip NV Data POST -// #define USE_LIBRARY_TIME_FUNCTIONS 1 // Use the C library functions mktime() and gmtime() for epoch<=>date conversions #define DISABLE_AIR_TRAP_LEVELING_ALARM 1 // Disable air trap level control alarms // #define DISABLE_3WAY_VALVES 1 // Disable 3-way valves // #define TST_3WAY_VALVES_ALWAYS_OPEN 1 // After POST and homing, open all 4 valves // #define DISABLE_ACCELS 1 // Disable accelerometer POST and monitoring // #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages // #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks -// #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks -// #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks + #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks +// #define ENABLE_ALTERNATE_FLOW 1 // Enable calculation of speed/pressure based flow and publish in lieu of MC motor speed + #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks // #define DISABLE_PUMP_DIRECTION_CHECKS 1 // Do not error on HD pump direction checks #define DISABLE_SYRINGE_PUMP 1 // Disable syringe pump functionality #define ALWAYS_ALLOW_SYRINGE_PUMP_CMDS 1 // Allow syringe pump commands at any time except when pump is busy #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks // #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks -// #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position - #define SKIP_CAL_CHECK 1 + #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position + #define SKIP_CAL_CHECK 1 // // #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) // #define RAW_FLOW_SENSOR_DATA 1 // Test build will not filter flow sensor data // #define READ_FPGA_ASYNC_DATA 1 // Test build reads non-priority register page every other time @@ -76,7 +76,7 @@ // #define DISABLE_UI_POST_TEST 1 // Disable the UI POST // Skip Pre-Treatment and get to treatment as soon as possible -// #define SKIP_UI_INTERACTION 1 // Skip UI interaction. + #define SKIP_UI_INTERACTION 1 // Skip UI interaction. #define SKIP_SAMPLE_WATER 1 // Skip pre-treatment sample water #define SKIP_CONSUMABLE_TESTS 1 // Skip pre-treatment consumable Self-tests #define SKIP_DRY_SELF_TESTS 1 // Skip pre-treatment dry self-tests Index: firmware/App/Modes/BloodPrime.c =================================================================== diff -u -r685e17a553a4fdf7dd8b3715e95d151eeff3c866 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision 685e17a553a4fdf7dd8b3715e95d151eeff3c866) +++ firmware/App/Modes/BloodPrime.c (.../BloodPrime.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -51,7 +51,7 @@ #define BLOOD_PRIME_INIT_BP_FLOW_RATE_ML_MIN 100 /// Interval at which blood prime ramping is controlled. -static const U32 BLOOD_PRIME_RAMPING_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); +static const U32 BLOOD_PRIME_RAMPING_INTERVAL = ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); /// Interval at which blood prime progress is to be published to UI. #define BLOOD_PRIME_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r685e17a553a4fdf7dd8b3715e95d151eeff3c866 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 685e17a553a4fdf7dd8b3715e95d151eeff3c866) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -130,6 +130,10 @@ switch ( postState ) { case POST_STATE_START: + if ( getMonitoredLineLevel( MONITORED_LINE_24V ) < MIN_24V_MEASURED_FOR_AC ) + { + initiatePowerOff(); + } sendUIVersionRequest(); postState = POST_STATE_FW_INTEGRITY; break; Index: firmware/App/Modes/ModePostTreat.c =================================================================== diff -u -r8466e63f95f65a3ffb18c3af85ac99328e41167b -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) +++ firmware/App/Modes/ModePostTreat.c (.../ModePostTreat.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -337,6 +337,7 @@ for ( valve = VDI; valve < NUM_OF_VALVES; ++valve ) { + setValvePosition( valve, VALVE_POSITION_A_INSERT_EJECT ); homeValve( valve ); } Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -r2637b1aada1cd724952d1b80de139804bb7b675b -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 2637b1aada1cd724952d1b80de139804bb7b675b) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -55,6 +55,8 @@ #define RINSEBACK_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Maximum time allowed for rinseback operation until full volume is delivered. Timer is reset whenever BP is running. static const U32 MAX_RINSEBACK_TIME = ( 5 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); +/// Maximum time allowed after rinseback operation completed. Timer is reset whenever BP is running (additional). +static const U32 MAX_RINSEBACK_DONE_TIME = ( 15 * SEC_PER_MIN * ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); /// Maximum time allowed for each additional rinseback volume delivery. static const U32 MAX_RINSEBACK_ADDITIONAL_TIME = ( 20 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ); /// Multiplier to convert flow (mL/min) into volume (mL) for period of general task interval. @@ -513,17 +515,22 @@ { RINSEBACK_STATE_T result = RINSEBACK_STOP_STATE; - // If user confirms ready to start re-circulate sub-mode, go there - if ( TRUE == recircRequested ) + // Have we been in this stopped state for too long w/o having delivered full blood volume back to patient? + if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < TARGET_RINSEBACK_VOLUME_ML ) ) { - signalRinsebackToRecirc(); + signalGoToTreatmentStopped(); + activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); } - // Has rinseback operation exceeded max time w/o delivering full volume? - if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < TARGET_RINSEBACK_VOLUME_ML ) ) + // Have we been in this stopped state for too long despite having delivered full blood volume back to patient? + else if ( ( rinsebackTimerCtr > MAX_RINSEBACK_DONE_TIME ) && ( getRinsebackVolume() >= TARGET_RINSEBACK_VOLUME_ML ) ) { signalGoToTreatmentStopped(); activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); } + else if ( TRUE == recircRequested ) + { + signalRinsebackToRecirc(); + } else if ( TRUE == additionalRinsebackRequested ) { additionalRinsebackRequested = FALSE; @@ -716,6 +723,7 @@ { result = TRUE; incrRinsebackFlowRateRequested = TRUE; + rinsebackPublishTimerCtr = getPublishRinsebackInterval(); } else { @@ -750,6 +758,7 @@ { result = TRUE; decrRinsebackFlowRateRequested = TRUE; + rinsebackPublishTimerCtr = getPublishRinsebackInterval(); } else { Index: firmware/App/Services/WatchdogMgmt.c =================================================================== diff -u -rd27dcf1fbbc9651636f211028917a1c0702bb56a -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision d27dcf1fbbc9651636f211028917a1c0702bb56a) +++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -182,12 +182,14 @@ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 2.0, v24 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } +#ifndef DISABLE_ALARM_AUDIO // Verify backup alarm audio is on when w.d. expired else if ( audioCurrent < MIN_BACKUP_ALARM_CURRENT_MA ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 3.0, audioCurrent ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } +#endif } else { @@ -212,12 +214,14 @@ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 4.0, v24 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } +#ifndef DISABLE_ALARM_AUDIO // Verify backup alarm audio is on when w.d. recovered else if ( audioCurrent > MAX_BACKUP_ALARM_CURRENT_MA ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_WATCHDOG_POST_TEST_FAILED, 5.0, audioCurrent ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } +#endif else { watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED; Index: firmware/App/Tasks/TaskBG.c =================================================================== diff -u -r6419179374edcd65da462de84e8aeaefb7e20320 -r1c628bfd5d6414b74b8cbd083f66839888a8236b --- firmware/App/Tasks/TaskBG.c (.../TaskBG.c) (revision 6419179374edcd65da462de84e8aeaefb7e20320) +++ firmware/App/Tasks/TaskBG.c (.../TaskBG.c) (revision 1c628bfd5d6414b74b8cbd083f66839888a8236b) @@ -16,12 +16,14 @@ ***************************************************************************/ #include "Battery.h" +#include "Buttons.h" #include "HDCommon.h" #include "NVDataMgmt.h" #include "SafetyShutdown.h" #include "SystemComm.h" #include "TaskTimer.h" -#include "Timers.h" +#include "Timers.h" +#include "Voltages.h" #include "WatchdogMgmt.h" /** @@ -31,7 +33,8 @@ // ********** private definitions ********** -#define MAX_TIME_FOR_UI_TO_COMMUNICATE_MS 30000 ///< Maximum time we wait for UI to communicate after power up (30 seconds). +#define MAX_TIME_FOR_UI_TO_COMMUNICATE_MS 30000 ///< Maximum time we wait for UI to communicate after power up (30 seconds). +#define TIME_FOR_AC_CHECK_AFTER_POWER_UP_MS 2000 ///< Two seconds after power up, check to see if we have AC power. // ********** private data ********** @@ -59,13 +62,22 @@ if ( FALSE == uiCommunicated() ) { #ifndef BOARD_WITH_NO_HARDWARE -#ifndef SIMULATE_UI +#ifndef SIMULATE_UI + // Check timeout waiting for UI to check in (via CAN) after startup. if ( TRUE == didTimeout( startUICommTimeout, MAX_TIME_FOR_UI_TO_COMMUNICATE_MS ) ) { activateAlarmNoData( ALARM_ID_UI_COMM_POST_FAILED ); - } + } #endif -#endif +#endif + // Two seconds after power up, check to see if we have AC power. If not, power down HD. + if ( TIME_FOR_AC_CHECK_AFTER_POWER_UP_MS == calcTimeSince( startUICommTimeout ) ) + { + if ( getMonitoredLineLevel( MONITORED_LINE_24V ) < MIN_24V_MEASURED_FOR_AC ) + { + initiatePowerOff(); + } + } } // Manage the watchdog