Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r101bf85b0b425e919b01b4b7fabcbd15fd5bbde5 -rde169e7374f6c7a737995ac8c6c3953dc5c75aa7 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 101bf85b0b425e919b01b4b7fabcbd15fd5bbde5) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision de169e7374f6c7a737995ac8c6c3953dc5c75aa7) @@ -35,9 +35,11 @@ // ********** private definitions ********** -#define MAX_UF_RATE_ML_PER_MIN 45.83 ///< Maximum ultrafiltration rate in mL/min (2750 mL/hr). +#define MAX_UF_RATE_ML_PER_HOUR 2750.0 ///< Maximum ultrafiltration rate in mL/hour +#define MAX_UF_RATE_ACCURACY_ERROR_ML_HR 100.0 ///< Maximum ultrafiltration rate accuracy error in mL/hr over each hour of treatment. +#define MAX_UF_RATE_ACCURACY_ERROR_PCT 0.05 ///< Minimum ultrafilteration rate accuracy in percentage of set point (5%) over each hour of treatment. #define MAX_UF_ACCURACY_ERROR_ML 250.0 ///< Maximum ultrafiltration accuracy error in mL over the entire treatment. -#define UF_ACCURACY_CHECK_INTERVAL ((1 * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL) ///< Ultrafiltration rate accuracy check interval count +#define UF_ACCURACY_CHECK_INTERVAL ((1 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND) / TASK_GENERAL_INTERVAL) ///< Ultrafiltration rate accuracy check interval count // ********** private data ********** @@ -58,6 +60,7 @@ static U32 setDialysateFlowRate; ///< Currently set dialysate flow rate (from prescription). static F32 maxUFVolumeML; ///< Currently set total ultrafiltration volume for treatment (from prescription). static F32 setUFRate; ///< Currently set ultrafiltration rate (from prescription). +static F32 maxUFRateAccuracyError_Ml_hr; ///< Minimum ultrafiltration rate accuracy over 1 hour duration (5% or 100 mL, whichever is greater). static U32 uFAccuracyCheckTimerCtr; ///< Timer counter to determine when next to check ultrafiltration accuracy. static F32 lastUFVolumeChecked; ///< Starting ultrafiltration volume for accuracy check. @@ -107,6 +110,7 @@ setDialysateFlowRate = 0; maxUFVolumeML = 0.0; setUFRate = 0.0; + maxUFRateAccuracyError_Ml_hr = MAX_UF_RATE_ACCURACY_ERROR_ML_HR; uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; @@ -149,6 +153,8 @@ setDialysateFlowRate = dPFlow; maxUFVolumeML = maxUFVol; setUFRate = uFRate; + maxUFRateAccuracyError_Ml_hr = MAX_UF_RATE_ACCURACY_ERROR_PCT * uFRate * (F32)MIN_PER_HOUR; + maxUFRateAccuracyError_Ml_hr = MAX( maxUFRateAccuracyError_Ml_hr, MAX_UF_RATE_ACCURACY_ERROR_ML_HR ); if ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) { @@ -601,37 +607,46 @@ /*********************************************************************//** * @brief * The checkUF function checks ultrafiltration accuracy for the last - * minute and checks total UF volume. Triggers an alarm if out of spec. + * hour and checks total UF volume. Triggers an alarm if out of spec. * @details * Inputs : uFAccuracyCheckTimerCtr, lastUFVolumeChecked, measUFVolume * Outputs : uFAccuracyCheckTimerCtr, lastUFVolumeChecked * @return none *************************************************************************/ static void checkUFAccuracyAndVolume( void ) { - // check UF accuracy at 1 minute intervals - if ( ++uFAccuracyCheckTimerCtr >= UF_ACCURACY_CHECK_INTERVAL ) - { - F32 uFMeasRate = measUFVolume - lastUFVolumeChecked; + F32 uFMeasRate = measUFVolume - lastUFVolumeChecked; - // check UF max rate - if ( uFMeasRate > MAX_UF_RATE_ML_PER_MIN ) - { + // check max UF rate in last hour // TODO - is this check necessary considering next check below is a tighter check on this? +// 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 ); +//#endif +// } + + // check UF rate diff from target in last hour + if ( uFMeasRate > maxUFRateAccuracyError_Ml_hr ) + { #ifndef DISABLE_UF_ALARMS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_UF_RATE_TOO_HIGH_ERROR, uFMeasRate ); #endif + } + // if actively performing ultrafiltration right now, increment timer and see if time to start another 1 hour check period + if ( ( DIALYSIS_UF_STATE == currentDialysisState ) && ( UF_RUNNING_STATE == currentUFState ) ) + { + if ( ++uFAccuracyCheckTimerCtr >= UF_ACCURACY_CHECK_INTERVAL ) + { + // reset for next check interval + lastUFVolumeChecked = measUFVolume; + uFAccuracyCheckTimerCtr = 0; } - // reset for next check - lastUFVolumeChecked = measUFVolume; - uFAccuracyCheckTimerCtr = 0; } // 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 ); -#endif } } Index: firmware/App/Modes/ModeTreatmentParams.c =================================================================== diff -u -rc3a59cba8736f085050b6fa74532eb68452d21fc -rde169e7374f6c7a737995ac8c6c3953dc5c75aa7 --- firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision c3a59cba8736f085050b6fa74532eb68452d21fc) +++ firmware/App/Modes/ModeTreatmentParams.c (.../ModeTreatmentParams.c) (revision de169e7374f6c7a737995ac8c6c3953dc5c75aa7) @@ -150,10 +150,12 @@ for ( param = 0; param < NUM_OF_TREATMENT_PARAMS; param++ ) { - resetCriticalData( &treatmentParameters[ param ] ); - // set each treatment parameter to its type and default value + // set type, range, and default value for each treatment parameter treatmentParameters[ param ].typ = treatParamsProperties[ param ].dataType; - setCriticalData( &treatmentParameters[ param ], treatParamsProperties[ param ].def ); + treatmentParameters[ param ].minimum = treatParamsProperties[ param ].min; + treatmentParameters[ param ].maximum = treatParamsProperties[ param ].max; + treatmentParameters[ param ].defValue = treatParamsProperties[ param ].def; + resetCriticalData( &treatmentParameters[ param ] ); // set staged parameter values to zero stagedParams[ param ].uInt = 0; } @@ -309,7 +311,10 @@ // set all treatment parameters (except UF volume which is not yet received) for ( param = TREATMENT_PARAM_FIRST_UINT; param < TREATMENT_PARAM_UF_VOLUME; param++ ) { - setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ); + if ( FALSE == setCriticalData( &treatmentParameters[ param ], stagedParams[ param ] ) ) + { + // TODO - should never get here - s/w fault? + } } // retain original settings for treatment that may be adjusted later during treatment origTreatmentParams.bloodFlowRate_mL_min = getCriticalData( &treatmentParameters[ TREATMENT_PARAM_BLOOD_FLOW ] ).uInt; @@ -552,22 +557,26 @@ * Outputs : treatmentParameters[] * @param param ID of treatment parameter to set unsigned integer value for * @param value unsigned integer value to assign to given treatment parameter - * @return none + * @return TRUE if set was successful, FALSE if not *************************************************************************/ -void setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ) +BOOL setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ) { + BOOL result = FALSE; + // validate parameter if ( param <= TREATMENT_PARAM_LAST_UINT ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.uInt = value; - setCriticalData( &treatmentParameters[ param ], data ); + result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_U32_PARAM, (U32)param ) } + + return result; } /*********************************************************************//** @@ -579,22 +588,26 @@ * Outputs : treatmentParameters[] * @param param ID of treatment parameter to set signed integer value for * @param value signed integer value to assign to given treatment parameter - * @return none + * @return TRUE if set was successful, FALSE if not *************************************************************************/ -void setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ) +BOOL setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ) { + BOOL result = FALSE; + // validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_INT ) && ( param <= TREATMENT_PARAM_LAST_INT ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.sInt = value; - setCriticalData( &treatmentParameters[ param ], data ); + result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_S32_PARAM, (U32)param ) } + + return result; } /*********************************************************************//** @@ -606,22 +619,26 @@ * Outputs : treatmentParameters[] * @param param ID of treatment parameter to set floating point value for * @param value floating point value to assign to given treatment parameter - * @return none + * @return TRUE if set was successful, FALSE if not *************************************************************************/ -void setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ) +BOOL setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ) { + BOOL result = FALSE; + // validate parameter if ( ( param >= TREATMENT_PARAM_FIRST_F32 ) && ( param < NUM_OF_TREATMENT_PARAMS ) ) { CRITICAL_DATAS_T data = treatmentParameters[ param ].data; data.sFlt = value; - setCriticalData( &treatmentParameters[ param ], data ); + result = setCriticalData( &treatmentParameters[ param ], data ); } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_PARAMS_INVALID_SET_F32_PARAM, (U32)param ) } + + return result; } /*********************************************************************//** @@ -739,18 +756,15 @@ // set parameter per its type if ( CRITICAL_DATA_TYPE_U32 == treatParamsProperties[ param ].dataType ) { - setTreatmentParameterU32( param, value.uInt ); - result = TRUE; + result = setTreatmentParameterU32( param, value.uInt ); } else if ( CRITICAL_DATA_TYPE_S32 == treatParamsProperties[ param ].dataType ) { - setTreatmentParameterS32( param, value.sInt ); - result = TRUE; + result = setTreatmentParameterS32( param, value.sInt ); } else { - setTreatmentParameterF32( param, value.sFlt ); - result = TRUE; + result = setTreatmentParameterF32( param, value.sFlt ); } } } Index: firmware/App/Modes/ModeTreatmentParams.h =================================================================== diff -u -r5eda37efda2d771de4f5cfb509adf05621a290c3 -rde169e7374f6c7a737995ac8c6c3953dc5c75aa7 --- firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision 5eda37efda2d771de4f5cfb509adf05621a290c3) +++ firmware/App/Modes/ModeTreatmentParams.h (.../ModeTreatmentParams.h) (revision de169e7374f6c7a737995ac8c6c3953dc5c75aa7) @@ -77,9 +77,9 @@ BOOL signalUserConfirmationOfTreatmentParameters( void ); // User has confirmed treatment parameters BOOL signalUserCancelTreatment( void ); // User has cancelled treatment -void setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ); // Set a specified unsigned integer treatment parameter value -void setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ); // Set a specified signed integer treatment parameter value -void setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ); // Set a specified floating point treatment parameter value +BOOL setTreatmentParameterU32( TREATMENT_PARAM_T param, U32 value ); // Set a specified unsigned integer treatment parameter value +BOOL setTreatmentParameterS32( TREATMENT_PARAM_T param, S32 value ); // Set a specified signed integer treatment parameter value +BOOL setTreatmentParameterF32( TREATMENT_PARAM_T param, F32 value ); // Set a specified floating point treatment parameter value U32 getTreatmentParameterU32( TREATMENT_PARAM_T param ); // Get a specified unsigned integer treatment parameter S32 getTreatmentParameterS32( TREATMENT_PARAM_T param ); // Get a specified signed integer treatment parameter F32 getTreatmentParameterF32( TREATMENT_PARAM_T param ); // Get a specified floating point treatment parameter Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r5eda37efda2d771de4f5cfb509adf05621a290c3 -rde169e7374f6c7a737995ac8c6c3953dc5c75aa7 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 5eda37efda2d771de4f5cfb509adf05621a290c3) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision de169e7374f6c7a737995ac8c6c3953dc5c75aa7) @@ -138,6 +138,7 @@ { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_ACCELEROMETER_FAILURE { ALARM_PRIORITY_HIGH, 0, ALARM_ID_NO_ALARM, TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , TRUE , FALSE }, // ALARM_ID_DG_CRITICAL_DATA_ERROR { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE + { ALARM_PRIORITY_HIGH, ALM_ESC_4_MIN, ALARM_ID_BLOOD_SITTING_WARNING, FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // ALARM_ID_INLET_WATER_PRESSURE_FAULT }; /// A blank alarm data record for alarms that do not include alarm data when triggered.