Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -rac029c36127b916d68c0039a470c3e4c68879adf -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision ac029c36127b916d68c0039a470c3e4c68879adf) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -50,8 +50,7 @@ #define MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM 2000.0F ///< Maximum allowed high conductivity value in uS/cm. #define MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM 1990.0F ///< Minimum allowed high conductivity value in uS/cm. -#define MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 200.0F ///< Maximum allowed low conductivity value in uS/cm. -#define MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 220.0F ///< Minimum allowed low conductivity value in uS/cm. +#define MIN_CPI_INLET_ALARM_RECOVERY_OFFSET_US_PER_CM 10.0F ///< Minimum inlet water conductivity recovery offset value in uS/cm. #define MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 100.0F ///< Maximum RO only mode high conductivity value in uS/cm. #define MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 90.0F ///< Minimum RO only mode high conductivity value in uS/cm. @@ -85,6 +84,8 @@ #define COND_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Conductivity sensors FPGA error timeout in milliseconds. #define COND_SENSORS_BAD_CHAR_TIME_OUT_MS ( 2 * MS_PER_SECOND ) ///< Conductivity sensor bad received character timeout in milliseconds. +#define MIN_CPI_CPO_COND_VALUES_AFTER_CALS_US_PER_CM 20.0F ///< Minimum allowed CPi and CPo conductivity values after calculations in uS/cm. + #pragma pack(push,1) /// Emstat pico measurement data package structure typedef struct @@ -146,6 +147,7 @@ static DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< Conductivity sensors' calibration record. static DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T condSensorsTempCompCalRecord; ///< Conductivity sensors' temperature compensation calibration record. static CAL_DATA_DG_COND_SENSORS_T condSensorCalTable[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Conductivity sensors calibration table. +static F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. // ********** private function prototypes ********** @@ -169,8 +171,9 @@ void initConductivitySensors( void ) { U08 i; - roRejectionRatio = 0.0F; - condDataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + roRejectionRatio = 0.0F; + condDataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + minInletWaterCondAlarmLimitUSPCM = 0.0F; for ( i = 0; i < NUM_OF_CONDUCTIVITY_SENSORS; i++ ) { @@ -349,7 +352,7 @@ if ( FALSE == isROOnlyModeEnabled() ) { - isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + isConductTooLow = ( conductivity < minInletWaterCondAlarmLimitUSPCM ? TRUE : FALSE ); isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); } else @@ -366,11 +369,11 @@ case DG_MODE_STAN: if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE ) ) { - isConductTooLow = ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? FALSE : TRUE ); + isConductTooLow = ( conductivity >= ( minInletWaterCondAlarmLimitUSPCM + MIN_CPI_INLET_ALARM_RECOVERY_OFFSET_US_PER_CM ) ? FALSE : TRUE ); } // Per PRS 403 - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, minInletWaterCondAlarmLimitUSPCM ); if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) { @@ -397,7 +400,7 @@ // Per PRS 403 checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); // Per PRS 404 - checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, isConductTooLow, conductivity, minInletWaterCondAlarmLimitUSPCM ); break; default: @@ -409,10 +412,10 @@ else { // VPI is closed - clear all alarms - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, FALSE, conductivity, minInletWaterCondAlarmLimitUSPCM ); checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); - checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, FALSE, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, FALSE, conductivity, minInletWaterCondAlarmLimitUSPCM ); } } @@ -448,6 +451,21 @@ /*********************************************************************//** * @brief + * The setMinInletWaterConductivityAlarmLimitUSPCM function sets the min + * inlet water conductivity alarm limit in uS/cm. + * @details Inputs: none + * @details Outputs: minInletWaterConductivityAlarmLimitUSPCM + * @param conductivity value + * @return none + *************************************************************************/ +void setMinInletWaterConductivityAlarmLimitUSPCM( F32 valueUSPM ) +{ + minInletWaterCondAlarmLimitUSPCM = valueUSPM; + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_MIN_INLET_WATER_COND_ALARM_FROM_HD_INSTIT_RECORD, minInletWaterCondAlarmLimitUSPCM, 0.0F ) +} + +/*********************************************************************//** + * @brief * The getConductivityValue function gets the compensated conductivity * value for a given conductivity sensor id. * @details Inputs: compensatedConductivityValues[] @@ -730,9 +748,19 @@ F32 temperature = getTemperatureValue( readPackage->sensors[ boardSensorIndex ].condSnsrTempSnsr ); F32 conductivity = ( 1.0F / resistance ) * SIEMENS_TO_MICROSIEMENS_CONVERSION; F32 compensatedCond = calcCompensatedConductivity( sensorId, conductivity, temperature ); + F32 calAppliedCond = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + if ( ( CONDUCTIVITYSENSORS_CPI_SENSOR == sensorId ) || ( CONDUCTIVITYSENSORS_CPO_SENSOR == sensorId ) ) + { + // If the CPi or CPo sensors values < 20 uS/cm after compensation and calibration, they are set to 20 uS/cm. + if ( calAppliedCond < MIN_CPI_CPO_COND_VALUES_AFTER_CALS_US_PER_CM ) + { + calAppliedCond = MIN_CPI_CPO_COND_VALUES_AFTER_CALS_US_PER_CM; + } + } + condSensorStatus[ sensorId ].internalErrorCount = 0; - condSensorStatus[ sensorId ].compensatedCondValue.data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + condSensorStatus[ sensorId ].compensatedCondValue.data = calAppliedCond; condSensorStatus[ sensorId ].rawCondValue = conductivity; } Index: firmware/App/Controllers/ConductivitySensors.h =================================================================== diff -u -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Controllers/ConductivitySensors.h (.../ConductivitySensors.h) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) +++ firmware/App/Controllers/ConductivitySensors.h (.../ConductivitySensors.h) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -94,6 +94,7 @@ void checkInletWaterConductivity( void ); void setCondcutivitySensorCalTable( CONDUCTIVITY_SENSORS_T sensor, CAL_DATA_DG_COND_SENSORS_T calTable ); +void setMinInletWaterConductivityAlarmLimitUSPCM( F32 valueUSPM ); F32 getConductivityValue( U32 sensorId ); Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r18a83ba64d9560ce8c4c009560ec1391ae15102f -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 18a83ba64d9560ce8c4c009560ec1391ae15102f) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -66,7 +66,6 @@ #define ACID_PERCENT_FILL 0.02222F ///< Acid volume percentage of reservoir volume. #define DATA_PUBLISH_COUNTER_START_COUNT 70 ///< Data publish counter start count. #define DRAIN_MODE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the drain mode data is published on the CAN bus. -#define MIN_CONCENTRATE_VOLUME_ML 500.0F ///< Minimum concentrate volume in milliliters. // ********** private data ********** @@ -276,18 +275,8 @@ // if we have reached our target drain to volume (by weight) or cannot drain anymore, we are done draining - go back to generation idle mode if ( TRUE == drainStatus ) { - DG_ACID_CONCENTRATES_RECORD_T acid; - F32 acidBottleVolML; - DG_BICARB_CONCENTRATES_RECORD_T bicarb; - F32 bicarbBottleVolML; - - getAcidConcentrateCalRecord( &acid ); - getBicarbConcentrateCalRecord( &bicarb ); signalDrainPumpHardStop(); - acidBottleVolML = acid.acidConcentrate[ CAL_DATA_ACID_CONCENTRATE_1 ].acidFullBottleVolumeML; - bicarbBottleVolML = bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbStartVolumeML; - if ( DG_RESERVOIR_1 == inactiveReservoir ) { setValveState( VRD1, VALVE_STATE_CLOSED ); @@ -297,36 +286,6 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); } -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_EMPTY_BOTTLES_ALARM ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - HD_MODE_SUB_MODE_T hdMode; - - getHDOperationMode( &hdMode ); - - // Detect empty bottles using integrated volumes - if ( ( ( acidBottleVolML - getChemicalUsedVolumeML( ACID ) ) <= MIN_CONCENTRATE_VOLUME_ML ) && // SRSDG 836 - ( hdMode.hdMode != MODE_POST ) && // don't care about concentrates after treatment complete - ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) - { - resetChemicalUsedVolumeML( ACID ); - setThisFirstFillFlag( TRUE ); // indicates bottles need prime - activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); - activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); - } - - if ( ( ( bicarbBottleVolML - getChemicalUsedVolumeML( BICARB ) ) <= MIN_CONCENTRATE_VOLUME_ML ) && // SRSDG 837 - ( hdMode.hdMode != MODE_POST ) && // don't care about concentrates after treatment complete - ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) - { - resetChemicalUsedVolumeML( BICARB ); - setThisFirstFillFlag( TRUE ); - activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); - activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); - } - } - if ( TRUE == isReservoirTarePending() ) { // Tare reservoir load cells at empty if requested result = DG_DRAIN_STATE_TARE; Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r00b244580f01f3cbd1b7d2d5a14ee61675bf4642 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 00b244580f01f3cbd1b7d2d5a14ee61675bf4642) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -76,7 +76,6 @@ #define DELAY_FMP_CHECK_START_BY_MS ( 10 * MS_PER_SECOND ) ///< Delay start of FMP check during dialysate deliver state by this amount of time (in ms). #define CONCENTRATE_TEST_COND_COLLECTION_DELAY_MS ( 5 * MS_PER_SECOND ) ///< Concentrate test conductivity data collection delay in milliseconds. -#define MAX_RO_REJECTION_RATIO_ALLOW 0.10F ///< Maximum RO rejection ratio. #define MAX_CPO_CONDUCTIVITY_ALLOW 100.0F ///< Maximum CPo sensor conductivity value. #define MIN_FILL_TARGET_TO_CHECK_RO_AND_CPO_ML 550 ///< Minimum fill target to check the RO and CPo alarms in milliliters. @@ -117,6 +116,7 @@ F32 fillFlowRateAverageLPM; ///< Fill flow average value in L/min. F32 fillLastTemperature; ///< Fill last temperature value. BOOL isThisFirstFill; ///< Fill flag to indicate whether it is the first fill or not. + BOOL isPrimeCondChecksSkipped; ///< Fill flag to indicate whether the acid and bicarb conductivity checks should be skipped after priming. } FILL_CONDITION_STATUS_T; /// Fill acid and bicarb types @@ -171,8 +171,8 @@ // NOTE: This variable should be initialized here because the init function is called every time and then it cannot be initialized there. This variable is // set via Dialin for calibration check purposes only static DIALIN_FILL_FOR_CAL_CHECK_T dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; ///< Dialin fill for calibration check. -static OVERRIDE_F32_T usedAcidVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated acid concentration volume has been used in mL. -static OVERRIDE_F32_T usedBicarbVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated bicarb concentration volume has been used in mL. +// NOTE: this variable should be initialized here because the init function is called every time and then this variable is set to 0. +static U32 minRORejectionRatioPCTFromHD = 0; ///< Min RO rejection ratio in percent from HD. static OVERRIDE_U32_T fillModeDataPublishInterval = { FILL_MODE_DATA_PUB_INTERVAL, FILL_MODE_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish fill mode data to CAN bus. static OVERRIDE_F32_T integratedVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< Total RO flow rate over period of time. @@ -194,7 +194,6 @@ static void handleDialysateMixing( F32 measuredROFlowRate_mL_min, F32 acidMixingRatio, F32 bicarbMixingRatio ); static BOOL isValueWithinPercentRange( F32 testValue, F32 baseValue, F32 percentFactor ); static void publishFillModeData( void ); -static void updateChemicalsUsage( void ); /*********************************************************************//** * @brief @@ -353,7 +352,6 @@ { checkDialysateTemperatureSensors(); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); - updateChemicalsUsage(); if ( fillState != DG_FILL_MODE_STATE_PAUSED ) { @@ -477,9 +475,10 @@ fillStatus.fillTemperatureRunningSum = 0.0F; // At the beginning the last and average temperatures are considered as the trimmer heater target temperature which // is the dialysate temperature - fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); - fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; - fillStatus.isThisFirstFill = TRUE; + fillStatus.fillTemperatureAverage = getHeaterTargetTemperature( DG_TRIMMER_HEATER ); + fillStatus.fillLastTemperature = getHeaterTargetTemperature( DG_TRIMMER_HEATER ) + RESERVOIR_EXTRA_TEMPERATURE; + fillStatus.isThisFirstFill = TRUE; + fillStatus.isPrimeCondChecksSkipped = FALSE; } /*********************************************************************//** @@ -497,60 +496,6 @@ /*********************************************************************//** * @brief - * The getChemicalUsedVolumeML function returns the consumed volume of the called - * chemical bottle in milliliters. - * @details Inputs: none - * @details Outputs: none - * @param bottle which the type of bottle (acid or bicarb) can be specified - * @return used chemical volume in millilters - *************************************************************************/ -F32 getChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ) -{ - F32 volume; - - if ( ACID == bottle ) - { - volume = getF32OverrideValue( &usedAcidVolumeML ); - } - else if ( BICARB == bottle ) - { - volume = getF32OverrideValue( &usedBicarbVolumeML ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CHEMICAL_BOTTLE_SELECTED, bottle ) - } - - return volume; -} - -/*********************************************************************//** - * @brief - * The resetChemicalUsedVolumeML function resets the used volume of a chemical - * bottle. - * @details Inputs: none - * @details Outputs: none - * @param bottle which the type of bottle (acid or bicarb) can be specified - * @return none - *************************************************************************/ -void resetChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ) -{ - if ( ACID == bottle ) - { - usedAcidVolumeML.data = 0.0F; - } - else if ( BICARB == bottle ) - { - usedBicarbVolumeML.data = 0.0F; - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CHEMICAL_BOTTLE_SELECTED, bottle ) - } -} - -/*********************************************************************//** - * @brief * The setThisFisrtFillFlag function sets the boolean flag that indicates * the acid and bicarb bottle need priming. * @details Inputs: none @@ -608,6 +553,23 @@ /*********************************************************************//** * @brief + * The setMinRORejectionRatioPCT function sets the RO rejection ratio in + * percent that has been received from the HD institutional record. + * @details Inputs: none + * @details Outputs: roRejectionRatioFromHD + * @param RO rejection ratio + * @return none + *************************************************************************/ +void setMinRORejectionRatioPCT( U32 roRejectionRatio ) +{ + U32 priorMinRORejectionRatio = minRORejectionRatioPCTFromHD; + + minRORejectionRatioPCTFromHD = roRejectionRatio; + SEND_EVENT_WITH_2_U32_DATA( DG_EVENT_MIN_RO_REJECTION_RATIO_PCT_FROM_HD_INSTIT_RECORD, priorMinRORejectionRatio, minRORejectionRatioPCTFromHD ) +} + +/*********************************************************************//** + * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. @@ -710,7 +672,7 @@ } else { - result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + result = ( FALSE == fillStatus.isPrimeCondChecksSkipped ? DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY : DG_FILL_MODE_STATE_PRODUCE_DIALYSATE ); setModeFillStateTransition( result ); } } @@ -962,16 +924,21 @@ { F32 avgCPo = sumFillCPoConductivity / (F32)fillCPoConductivitySampleCnt; // sample count incremented above w/o condition so no need for divide by zero checks F32 avgRR = sumFillRejRatio / (F32)fillCPoConductivitySampleCnt; + // The rejection ratio = 1 - (institutional RR value in percent) / 100 + // If the instit RR value is 0% the converted RR becomes 1. But If the instit RR value is 0, the RR alarm is not checked + F32 convRR = 1.0F - ( ( (F32)minRORejectionRatioPCTFromHD ) / FRACTION_TO_PERCENT_FACTOR ); + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_CALC_RO_REJECTION_RATIO, convRR, avgRR ) + if ( ( avgCPo > MAX_CPO_CONDUCTIVITY_ALLOW ) && ( getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) != TRUE ) ) { // Fault alarm per PRS 483 SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, avgCPo, MAX_CPO_CONDUCTIVITY_ALLOW ); } - if ( ( avgRR > MAX_RO_REJECTION_RATIO_ALLOW ) && ( isROOnlyModeEnabled() != TRUE ) ) + if ( ( avgRR > convRR ) && ( isROOnlyModeEnabled() != TRUE ) && ( minRORejectionRatioPCTFromHD > 0 ) ) { // Fault alarm per PRS 483 - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, MAX_RO_REJECTION_RATIO_ALLOW ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, convRR ); } } @@ -995,8 +962,9 @@ { setBadAvgConductivityDetectedFlag( TRUE ); // signal idle bad avg conductivity detected setThisFirstFillFlag( TRUE ); - resetChemicalUsedVolumeML( BICARB ); - resetChemicalUsedVolumeML( ACID ); + // Bad fill conductivity. Set this flag so after priming the concentrate lines, acid and bicarb conductivities are not checked + // again to save time + fillStatus.isPrimeCondChecksSkipped = TRUE; SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConduSPerCM, bicarbNormalConduSPerCM ); // trigger replace bottles alarm #1 clearAlarm( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); // clear this alarm before triggering in case previous fill was bad and still active from before activateAlarmNoData ( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); @@ -1145,8 +1113,9 @@ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONCENTRATE_PUMP_MAX_SPEED ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - concPumpPrimeStartTimeMS = getMSTimerCount(); - fillStatus.isThisFirstFill = FALSE; + concPumpPrimeStartTimeMS = getMSTimerCount(); + fillStatus.isThisFirstFill = FALSE; + fillStatus.isPrimeCondChecksSkipped = FALSE; if ( ( DIALIN_FILL_FOR_CAL_ACID_CHECK == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) { // After acid test, the state transitions to acid test. If the cal for check prime was set, transition to Gen Idle and @@ -1310,8 +1279,6 @@ fillModeData.averageBicarbConductivity = averageBicarbConductivity; fillModeData.isThisTheFirstFill = isThisTheFirstFill(); fillModeData.pctDiffInConductivity = pctDiffInConductivity; - fillModeData.usedAcidVolumeML = getChemicalUsedVolumeML( ACID ); - fillModeData.usedBicarbVolumeML = getChemicalUsedVolumeML( BICARB ); fillModeData.integratedVolumeML = getIntegratedVolumeML(); fillModeData.roOnlyModeStatus = (U32)isROOnlyModeEnabled(); fillModeData.badFillSignal = getCurrentBadFillSignal(); @@ -1323,123 +1290,13 @@ } } -/*********************************************************************//** - * @brief - * The updateChemicalsUsage function updates the used acid and bicarb volumes. - * @details Inputs: usedAcidVolumeML, usedBicarbVolumeML - * @details Outputs: none - * @return none - *************************************************************************/ -static void updateChemicalsUsage( void ) -{ - usedAcidVolumeML.data += getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP1_ACID ) * FLOW_INTEGRATOR; - usedBicarbVolumeML.data += getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP2_BICARB ) * FLOW_INTEGRATOR; -} - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - /*********************************************************************//** * @brief - * The testSetUsedAcidVolumeMLOverride function overrides the - * acid volume. - * @details Inputs: used acid volume - * @details Outputs: used acid volume - * @param value override used acid volume in mL - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetUsedAcidVolumeMLOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedAcidVolumeML.ovInitData = usedAcidVolumeML.data; - usedAcidVolumeML.ovData = value; - usedAcidVolumeML.override = OVERRIDE_KEY; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetUsedAcidVolumeMLOverride function resets the override - * of the used acid volume. - * @details Inputs: used acid volume - * @details Outputs: used acid volume - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testResetUsedAcidVolumeMLOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedAcidVolumeML.data = usedAcidVolumeML.ovInitData; - usedAcidVolumeML.override = OVERRIDE_RESET; - usedAcidVolumeML.ovInitData = 0.0F; - usedAcidVolumeML.ovData = 0.0F; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testSetUsedBicarbVolumeMLOverride function overrides the - * bicarb volume. - * @details Inputs: used bicarb volume - * @details Outputs: used bicarb volume - * @param value override used bicarb volume in mL - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetUsedBicarbVolumeMLOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedBicarbVolumeML.ovInitData = usedBicarbVolumeML.data; - usedBicarbVolumeML.ovData = value; - usedBicarbVolumeML.override = OVERRIDE_KEY; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetUsedBicarbVolumeMLOverride function resets the override - * of the used bicarb volume. - * @details Inputs: used bicarb volume - * @details Outputs: used bicarb volume - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testResetUsedBicarbVolumeMLOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - usedBicarbVolumeML.data = usedBicarbVolumeML.ovInitData; - usedBicarbVolumeML.override = OVERRIDE_RESET; - usedBicarbVolumeML.ovInitData = 0.0F; - usedBicarbVolumeML.ovData = 0.0F; - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief * The testSetFillModeDataPublishIntervalOverride function overrides the * fill mode data publish interval. * @details Inputs: FillModeDataPublishInterval @@ -1531,6 +1388,27 @@ /*********************************************************************//** * @brief + * The testSetEnableTestChemsCondValuesStatus function enables the testing + * of acid and bicarb conductivity values after priming. + * @details Inputs: none + * @details Outputs: fillStatus.isPrimeCondChecksSkipped + * @return TRUE if set successful, FALSE if not + *************************************************************************/ +BOOL testSetEnableTestChemsCondValuesStatus( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + fillStatus.isPrimeCondChecksSkipped = FALSE; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The testSetModeFillForCal function sets the variable to run mode fill only * for calibration check * @details Inputs: none Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -re3839e10decfadf12a8fb2b9f8c049d8a30e945b -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision e3839e10decfadf12a8fb2b9f8c049d8a30e945b) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -46,8 +46,6 @@ F32 averageAcidConductivity; ///< The average acid conductivity calculated in one fill. U32 isThisTheFirstFill; ///< Indicate if this is the first fill. F32 pctDiffInConductivity; ///< The percent difference between CD1 and CD2. - F32 usedAcidVolumeML; ///< The used acid volume in ML. - F32 usedBicarbVolumeML; ///< The used bicarb volume in ML. F32 integratedVolumeML; ///< Integrated volume in milliliters. U32 roOnlyModeStatus; ///< RO only mode status. U32 badFillSignal; ///< bad fill signal. @@ -71,26 +69,21 @@ BOOL isThisTheFirstFill( void ); -F32 getChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ); -void resetChemicalUsedVolumeML( CHEMICAL_BOTTLES_T bottle ); - void setROMode( BOOL enableROOnlyMode ); BOOL isROOnlyModeEnabled( void ); void setAcidAndBicarbType( U32 acid, U32 bicarb ); -BOOL testSetUsedAcidVolumeMLOverride( F32 value ); -BOOL testResetUsedAcidVolumeMLOverride( void ); +void setMinRORejectionRatioPCT( U32 roRejectionRatio ); -BOOL testSetUsedBicarbVolumeMLOverride( F32 value ); -BOOL testResetUsedBicarbVolumeMLOverride( void ); - BOOL testSetFillModeDataPublishIntervalOverride( U32 value ); BOOL testResetFillModeDataPublishIntervalOverride( void ); BOOL testSetIntegratedVolumeOverride( F32 value ); BOOL testResetIntegratedVolumeOverride( void ); +BOOL testSetEnableTestChemsCondValuesStatus( void ); + BOOL testSetModeFillForCal( U32 calForCheck ); /**@}*/ Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r7d0fd5ed6b9db0479af90477e5108f6d3fa8df17 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 7d0fd5ed6b9db0479af90477e5108f6d3fa8df17) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -59,9 +59,6 @@ // NOTE: the bad fill state must be initialized here and not in the transition function since in case of a bad fill, the transition function is called // several times to drain and fill and handle a bad fill. static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T badFillState = DG_HANDLE_BAD_FILL_STATE_START; ///< Initialize bad fill sub-state. -// NOTE: the empty bottle flag must be initialized here and not in transition function since this flag must be set to false once the empty bottle -// fill is finished. -static BOOL handleEmptyBottleFlag = FALSE; ///< Internal siganl flag to handle empty bottle flag. static U32 hdLostCommStartTime_ms; ///< Lost communication with HD start time in ms. static BOOL handleBadFillFlag; ///< Internal signal flag to handle bad fill. static OVERRIDE_U32_T genIdleDataPublicationInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, @@ -267,8 +264,8 @@ * @brief * The handleIdleStartState function executes the start state of the * generation idle mode state machine. - * @details Inputs: handleEmptyBottleFlag - * @details Outputs: handleEmptyBottleFlag, handleBadFillFlag, badFillState + * @details Inputs: handleBadFillFlag + * @details Outputs: badFillState * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleIdleStartState( void ) @@ -283,14 +280,6 @@ { badFillState = DG_HANDLE_BAD_FILL_STATE_START; result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; - - if ( ( TRUE == handleEmptyBottleFlag ) && ( DG_MODE_FILL == getPreviousOperationMode() ) ) - { - // If the previous mode was fill and the empty bottle flag was TRUE, set it to FALSE and clear the informative alarm - // Done with the empty bottle handling - handleEmptyBottleFlag = FALSE; - clearAlarmCondition( ALARM_ID_DG_CREATING_DIALYSATE_PLEASE_WAIT ); - } } return result; @@ -300,28 +289,14 @@ * @brief * The handleFlushWaterState function executes the flush water state * generation idle mode state machine. - * @details Inputs: handleEmptyBottleFlag - * @details Outputs: handleEmptyBottleFlag + * @details Inputs: none + * @details Outputs: none * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ) { DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; - if ( ( TRUE == isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) ) || ( TRUE == isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) ) ) - { - // The empty bottle alarms are active set the empty bottle alarm to TRUE. - handleEmptyBottleFlag = TRUE; - } - - if ( ( TRUE == handleEmptyBottleFlag ) && - ( isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) != TRUE ) && - ( isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) != TRUE ) ) - { - // User acknowledged empty conc bottle alarm(s) and so time to start a fill - startFillCmd( getTargetFillVolumeML(), getTargetFillFlowRateLPM() ); - } - return result; } Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r00b244580f01f3cbd1b7d2d5a14ee61675bf4642 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 00b244580f01f3cbd1b7d2d5a14ee61675bf4642) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -68,13 +68,15 @@ static BOOL pendingStartDGHeatDisinfectActiveCoolRequest; ///< Flag indicating HD has requested DG start heat disinfect active cool. static BOOL pendingStartDGChemicalDisinfectFlushRequest; ///< Flag indicating HD has requested DG start chemical disinfect flush. static BOOL pendingStartDGROPermeateSampleRequest; ///< Flag indicating HD has requested DG start RO permeate sample. +static BOOL haveDGInstitutionalValuesBeenRcvd; ///< Flag indicating DG has received DG institutional values. static OVERRIDE_U32_T filterFlushTimePeriod = { FILTER_FLUSH_TIME_MS, FILTER_FLUSH_TIME_MS, 0, 0 }; ///< Filter flush time period in ms. // ********** private function prototypes ********** static BOOL areInletWaterConditionsAlarmsActive( void ); +static void checkDGInstitutionalValuesReceived( void ); static DG_STANDBY_MODE_STATE_T handleStandbyIdleState( void ); static DG_STANDBY_MODE_STATE_T handleStandbyFlushFilterState( void ); @@ -90,7 +92,7 @@ * flushFilterRequest, endSampleWaterRequest, waterSampleStartTime, * filterFlushStartTime, filterFlushPublishTimerCounter, pendingStartDGRequest, * pendingStartDGHeatDisinfectActiveCoolRequest, - * pendingStartDGROPermeateSampleRequest + * pendingStartDGROPermeateSampleRequest, haveDGInstitutionalValuesBeenRcvd * @return none *************************************************************************/ void initStandbyMode( void ) @@ -109,6 +111,7 @@ pendingStartDGChemicalDisinfectRequest = FALSE; pendingStartDGHeatDisinfectActiveCoolRequest = FALSE; pendingStartDGROPermeateSampleRequest = FALSE; + haveDGInstitutionalValuesBeenRcvd = FALSE; // Reset the heaters efficiency for another treatment resetHeatersEstimationGain(); @@ -171,6 +174,8 @@ standbyState = DG_STANDBY_MODE_STATE_PAUSE; } + checkDGInstitutionalValuesReceived(); + // execute current Standby state switch ( standbyState ) { @@ -233,6 +238,26 @@ /*********************************************************************//** * @brief + * The checkDGInstitutionalValuesReceived function requests the DG institutional + * values from HD if HD is in standby and the values have not been received yet. + * @details Inputs: haveDGInstitutionalValuesBeenRcvd + * @details Outputs: None + * @return none + *************************************************************************/ +static void checkDGInstitutionalValuesReceived( void ) +{ + HD_MODE_SUB_MODE_T mode; + + getHDOperationMode( &mode ); + + if ( (mode.hdMode >= MODE_STAN ) && ( FALSE == haveDGInstitutionalValuesBeenRcvd ) ) + { + sendDGInstitutionalValuesRequestToHD(); + } +} + +/*********************************************************************//** + * @brief * The handleStandbyIdleState function executes the idle state of the * standby mode state machine. * @details Inputs: pendingSampleWaterRequest, pendingStartDGRequest, @@ -264,9 +289,6 @@ { pendingStartDGRequest = FALSE; signalSyncToHD(); - // About to start a treatment reset the chemical bottles volumes (regardless whether the user has inserted new bottles) - resetChemicalUsedVolumeML( BICARB ); - resetChemicalUsedVolumeML( ACID ); requestNewOperationMode( DG_MODE_GENE ); } else if ( TRUE == pendingStartDGFlushRequest ) @@ -492,7 +514,7 @@ { BOOL result = FALSE; - if ( DG_STANDBY_MODE_STATE_IDLE == standbyState ) + if ( ( DG_MODE_STAN == getCurrentOperationMode() ) && ( DG_STANDBY_MODE_STATE_IDLE == standbyState ) ) { result = TRUE; pendingStartDGRequest = TRUE; @@ -888,7 +910,20 @@ return standbyState; } +/*********************************************************************//** + * @brief + * The getDGInstitutionalValues function sets the signal DG institutional + * values have been received. + * @details Inputs: none + * @details Outputs: haveDGInstitutionalValuesBeenRcvd + * @return none + *************************************************************************/ +void signalDGInstituionalValuesReceived( void ) +{ + haveDGInstitutionalValuesBeenRcvd = TRUE; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/ModeStandby.h =================================================================== diff -u -re6c60e07b450ec8d58e87bf13d45f96efab54d8b -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision e6c60e07b450ec8d58e87bf13d45f96efab54d8b) +++ firmware/App/Modes/ModeStandby.h (.../ModeStandby.h) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -58,6 +58,8 @@ BOOL startDGROPermeateSample( void ); // HD start RO permeate sample +void signalDGInstituionalValuesReceived( void ); + BOOL testSetFilterFlushTimePeriodOverride( U32 value ); // set filter flush time period override. BOOL testResetFilterFlushTimePeriodOverride( void ); // reset filter flush time period override. Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -14,61 +14,61 @@ * @date (original) 20-May-2021 * ***************************************************************************/ - -#ifndef __ALARM_MGMT_SW_FAULTS_H__ -#define __ALARM_MGMT_SW_FAULTS_H__ - + +#ifndef __ALARM_MGMT_SW_FAULTS_H__ +#define __ALARM_MGMT_SW_FAULTS_H__ + /** * @addtogroup AlarmManagement * @{ */ -// ********** public definitions ********** - -// Listing of specific software faults for logging purposes. -typedef enum -{ - SW_FAULT_ID_NONE = 0, - SW_FAULT_ID_INT_ADC_DATA_OVERRUN, - SW_FAULT_ID_INT_ADC_INVALID_CHANNEL_REQUESTED, - SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE, - SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, - SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, // 5 - SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, - SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, - SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, - SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, - SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, // 10 - SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, - SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, - SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, - SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, - SW_FAULT_ID_FPGA_INVALID_IN_STATE, // 15 - SW_FAULT_ID_FPGA_INVALID_OUT_STATE, - SW_FAULT_ID_FPGA_WRITE_CMD_TOO_MUCH_DATA, - SW_FAULT_ID_FPGA_WRITE_RSP_TOO_MUCH_DATA, - SW_FAULT_ID_FPGA_READ_CMD_TOO_MUCH_DATA, - SW_FAULT_ID_FPGA_READ_RSP_TOO_MUCH_DATA, // 20 - SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL, - SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE, - SW_FAULT_ID_MSG_QUEUES_GET_INVALID_QUEUE, - SW_FAULT_ID_MSG_QUEUES_IS_EMPTY_INVALID_QUEUE, - SW_FAULT_ID_MSG_QUEUES_IS_FULL_INVALID_QUEUE, // 25 - SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_RTC_EXEC_INVALID_STATE, - SW_FAULT_ID_RTC_SELF_TEST_INVALID_STATE, - SW_FAULT_ID_RTC_TRANSACTION_SERVICE_INVALID_STATE, - SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL, // 30 - SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, - SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL, - SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE, - SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE, - SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, // 35 - SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, - SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, - SW_FAULT_ID_HEATERS_INVALID_EXEC_STATE, - SW_FAULT_ID_INVALID_EMSTAT_CONDUCTIVITY_BOARD_SELECTED, - SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, // 40 +// ********** public definitions ********** + +// Listing of specific software faults for logging purposes. +typedef enum +{ + SW_FAULT_ID_NONE = 0, + SW_FAULT_ID_INT_ADC_DATA_OVERRUN, + SW_FAULT_ID_INT_ADC_INVALID_CHANNEL_REQUESTED, + SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE, + SW_FAULT_ID_OP_MODES_ILLEGAL_MODE_TRANSITION_REQUESTED, + SW_FAULT_ID_OP_MODES_INVALID_MODE_STATE, // 5 + SW_FAULT_ID_OP_MODES_INVALID_MODE_REQUESTED, + SW_FAULT_ID_OP_MODES_INVALID_MODE_TO_TRANSITION_TO, + SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_ACTIVATE, + SW_FAULT_ID_ALARM_MGMT_INVALID_ALARM_TO_CLEAR, + SW_FAULT_ID_COMM_BUFFERS_ADD_TOO_MUCH_DATA, // 10 + SW_FAULT_ID_COMM_BUFFERS_ADD_INVALID_BUFFER, + SW_FAULT_ID_COMM_BUFFERS_GET_INVALID_BUFFER, + SW_FAULT_ID_COMM_BUFFERS_PEEK_INVALID_BUFFER, + SW_FAULT_ID_COMM_BUFFERS_COUNT_INVALID_BUFFER, + SW_FAULT_ID_FPGA_INVALID_IN_STATE, // 15 + SW_FAULT_ID_FPGA_INVALID_OUT_STATE, + SW_FAULT_ID_FPGA_WRITE_CMD_TOO_MUCH_DATA, + SW_FAULT_ID_FPGA_WRITE_RSP_TOO_MUCH_DATA, + SW_FAULT_ID_FPGA_READ_CMD_TOO_MUCH_DATA, + SW_FAULT_ID_FPGA_READ_RSP_TOO_MUCH_DATA, // 20 + SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL, + SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE, + SW_FAULT_ID_MSG_QUEUES_GET_INVALID_QUEUE, + SW_FAULT_ID_MSG_QUEUES_IS_EMPTY_INVALID_QUEUE, + SW_FAULT_ID_MSG_QUEUES_IS_FULL_INVALID_QUEUE, // 25 + SW_FAULT_ID_WATCHDOG_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_RTC_EXEC_INVALID_STATE, + SW_FAULT_ID_RTC_SELF_TEST_INVALID_STATE, + SW_FAULT_ID_RTC_TRANSACTION_SERVICE_INVALID_STATE, + SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL, // 30 + SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, + SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL, + SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE, + SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, // 35 + SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, + SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, + SW_FAULT_ID_HEATERS_INVALID_EXEC_STATE, + SW_FAULT_ID_INVALID_EMSTAT_CONDUCTIVITY_BOARD_SELECTED, + SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, // 40 SW_FAULT_ID_VALVES_INVALID_VALVE_ID, SW_FAULT_ID_CAN_PARITY_ERROR, SW_FAULT_ID_CAN_PASSIVE_WARNING, @@ -79,7 +79,7 @@ SW_FAULT_ID_ACCEL_INVALID_STATE, SW_FAULT_ID_ACCEL_GET_INVALID_AXIS, SW_FAULT_ID_ACCEL_GET_MAX_INVALID_AXIS, // 50 - SW_FAULT_ID_ACCEL_INVALID_SELF_TEST_STATE, + SW_FAULT_ID_ACCEL_INVALID_SELF_TEST_STATE, SW_FAULT_ID_UTIL_INVALID_WIN_COUNT, SW_FAULT_ID_UTIL_INVALID_WIN_MAX_COUNT, SW_FAULT_ID_PERSISTENT_ALARM_INVALID_INDEX, @@ -131,7 +131,7 @@ SW_FAULT_ID_SAFETY_SHUTDOWN_INVALID_SELF_TEST_STATE, // 100 SW_FAULT_ID_PHANTOM_INTERRUPT, SW_FAULT_ID_ILLEGAL_MEM_ACCESS, - SW_FAULT_ID_INVALID_CHEMICAL_BOTTLE_SELECTED, + SW_FAULT_ID_INVALID_AVAILABLE_1, SW_FAULT_ID_INVALID_FPGA_SENSOR_GROUP_SELECTED, SW_FAULT_ID_INVALID_FLOW_SENSOR_SELECTED, // 105 SW_FAULT_ID_INVALID_SERVICE_STATE_SELECTED, @@ -152,9 +152,9 @@ SW_FAULT_ID_DG_INVALID_COND_SNSNR_CAL_TABLE_SELECTED, SW_FAULT_ID_DG_RO_PERMEATE_SAMPLE_INVALID_EXEC_STATE, SW_FAULT_ID_DG_RO_PERMEATE_SAMPLE_INVALID_MESSAGE, - NUM_OF_SW_FAULT_IDS -} SW_FAULT_ID_T; - + NUM_OF_SW_FAULT_IDS +} SW_FAULT_ID_T; + /**@}*/ -#endif +#endif Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -rac029c36127b916d68c0039a470c3e4c68879adf -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision ac029c36127b916d68c0039a470c3e4c68879adf) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -32,23 +32,23 @@ #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" -#include "Utilities.h" -#include "Valves.h" - -/** - * @addtogroup Reservoirs - * @{ - */ - -// ********** private definitions ********** - -#define MIN_RESERVOIR_VOLUME_ML 0 ///< Minimum reservoir volume in mL. -#define DEFAULT_FILL_VOLUME_ML 1500 ///< Default fill volume for treatment in mL. -#define MAX_FILL_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///< Maximum fill volume in mL. -#define DEFAULT_DRAIN_VOLUME_ML 0 ///< Default drain volume in mL. -#define MAX_DRAIN_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///< Maximum drain volume in mL. +#include "Utilities.h" +#include "Valves.h" -#define MIN_DRAIN_INLET_PSI_EMPTY -4.5F ///< Minimum drain inlet pressure (in PSI) to indicate reservoir is empty while drain pump on. +/** + * @addtogroup Reservoirs + * @{ + */ + +// ********** private definitions ********** + +#define MIN_RESERVOIR_VOLUME_ML 0 ///< Minimum reservoir volume in mL. +#define DEFAULT_FILL_VOLUME_ML 1500 ///< Default fill volume for treatment in mL. +#define MAX_FILL_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///< Maximum fill volume in mL. +#define DEFAULT_DRAIN_VOLUME_ML 0 ///< Default drain volume in mL. +#define MAX_DRAIN_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///< Maximum drain volume in mL. + +#define MIN_DRAIN_INLET_PSI_EMPTY -4.5F ///< Minimum drain inlet pressure (in PSI) to indicate reservoir is empty while drain pump on. #define RESERVOIR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< interval (ms/task time) at which the reservoir data is published on the CAN bus. #define MAX_REDUNDANT_LOAD_CELL_DIFF 50.0F ///< Maximum difference in redundant load cells when determining if fill completed. #define MAX_DRAIN_RPM_MLP 2400.0F ///< Maximum drain RPM in mL/min. @@ -98,10 +98,10 @@ BOOL hasROGenVolBeenWrittenToNV; ///< Boolean flag to indicate whether the generated RO volume has been written to NV or not. } NV_OPS_T; -static HEATERS_TEMPERATURE_CALC_DATA_T heatersTempCalc; ///< Heaters temperature calculations data structure. -static U32 dataPublishCounter; ///< used to schedule reservoir data publication to CAN bus. - -static OVERRIDE_U32_T activeReservoir = { 0, 0, 0, 0 }; ///< The active reservoir that serves the HD dialysate need. +static HEATERS_TEMPERATURE_CALC_DATA_T heatersTempCalc; ///< Heaters temperature calculations data structure. +static U32 dataPublishCounter; ///< used to schedule reservoir data publication to CAN bus. + +static OVERRIDE_U32_T activeReservoir = { 0, 0, 0, 0 }; ///< The active reservoir that serves the HD dialysate need. static OVERRIDE_U32_T fillVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir fill volume (in mL). static OVERRIDE_U32_T drainVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir drain volume (in mL). static OVERRIDE_U32_T reservoirDataPublishInterval = { RESERVOIR_DATA_PUB_INTERVAL, @@ -131,19 +131,19 @@ static void publishReservoirData( void ); -/*********************************************************************//** - * @brief - * The initReservoirs function initializes the Reservoirs module. - * @details Inputs: none +/*********************************************************************//** + * @brief + * The initReservoirs function initializes the Reservoirs module. + * @details Inputs: none * @details Outputs: activeReservoir.data, fillVolumeTargetMl.data, * drainVolumeTargetMl.data, targetFillFlowRateLPM, isThisTheFirstCycle, - * previousReservoiWeight, dataPublishCounter, nvOps - * @return none - *************************************************************************/ -void initReservoirs( void ) + * previousReservoiWeight, dataPublishCounter, nvOps + * @return none + *************************************************************************/ +void initReservoirs( void ) { activeReservoir.data = (U32)DG_RESERVOIR_1; - fillVolumeTargetMl.data = DEFAULT_FILL_VOLUME_ML; + fillVolumeTargetMl.data = DEFAULT_FILL_VOLUME_ML; drainVolumeTargetMl.data = DEFAULT_DRAIN_VOLUME_ML; targetFillFlowRateLPM = 0.0; isThisTheFirstCycle = TRUE; @@ -154,16 +154,16 @@ memset( &reservoirPreviousStatus, 0.0, sizeof( RESERVOIRS_PREVIOUS_STATUS ) * NUM_OF_DG_RESERVOIRS ); } - -/*********************************************************************//** - * @brief - * The execReservoirs function manages periodic tasks for the Reservoirs module. - * @details Inputs: dataPublishCounter, nvOps + +/*********************************************************************//** + * @brief + * The execReservoirs function manages periodic tasks for the Reservoirs module. + * @details Inputs: dataPublishCounter, nvOps * @details Outputs: dataPublishCounter, heatingConstsCalRecord, - * reservoirsCalRecord, nvOps - * @return none - *************************************************************************/ -void execReservoirs( void ) + * reservoirsCalRecord, nvOps + * @return none + *************************************************************************/ +void execReservoirs( void ) { // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) @@ -200,7 +200,7 @@ } } - publishReservoirData(); + publishReservoirData(); } /*********************************************************************//** @@ -241,16 +241,16 @@ return result; } -/*********************************************************************//** - * @brief - * The setActiveReservoirCmd function sets the given reservoir as active - * (meaning HD will be drawing from this reservoir). - * @details Inputs: none - * @details Outputs: Specified reservoir is set as active. - * @param resID ID of reservoir to set as active - * @return none - *************************************************************************/ -void setActiveReservoirCmd( DG_RESERVOIR_ID_T resID ) +/*********************************************************************//** + * @brief + * The setActiveReservoirCmd function sets the given reservoir as active + * (meaning HD will be drawing from this reservoir). + * @details Inputs: none + * @details Outputs: Specified reservoir is set as active. + * @param resID ID of reservoir to set as active + * @return none + *************************************************************************/ +void setActiveReservoirCmd( DG_RESERVOIR_ID_T resID ) { DG_CMD_RESPONSE_T cmdResponse; cmdResponse.commandID = DG_CMD_SWITCH_RESERVOIR; @@ -264,21 +264,21 @@ { case DG_RESERVOIR_1: activeReservoir.data = (U32)resID; - cmdResponse.rejected = FALSE; - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - break; - - case DG_RESERVOIR_2: + cmdResponse.rejected = FALSE; + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + break; + + case DG_RESERVOIR_2: activeReservoir.data = (U32)resID; - cmdResponse.rejected = FALSE; - setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); - setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); - setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - break; - - default: + cmdResponse.rejected = FALSE; + setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); + break; + + default: // invalid reservoir given - cmd will be NAK'd w/ false result. cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; break; @@ -377,11 +377,7 @@ fillVolumeTargetMl.data = fillToVolMl; cmdResponse.rejected = FALSE; - if ( ( FALSE == isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) ) && // reject moving to fill mode if - ( FALSE == isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) ) ) // alarm is active - { - requestNewOperationMode( DG_MODE_FILL ); - } + requestNewOperationMode( DG_MODE_FILL ); } else { Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -re6c60e07b450ec8d58e87bf13d45f96efab54d8b -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e6c60e07b450ec8d58e87bf13d45f96efab54d8b) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -977,6 +977,10 @@ handleSendDGServiceRecordToHD( message ); break; + case MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_RESPONSE: + handleDGInstitutionalValuesResponseFromHDInstitRecord( message ); + break; + // NOTE: This case must be last case MSG_ID_DG_TESTER_LOGIN_REQUEST: handleTesterLogInRequest( message ); @@ -1236,14 +1240,6 @@ handleTestFansRPMAlarmStartTimeOffsetRequest( message ); break; - case MSG_ID_DG_USED_ACID_VOLUME_ML_OVERRIDE: - handleTestUsedAcidVolumeMLOverrideRequest( message ); - break; - - case MSG_ID_DG_USED_BICARB_VOLUME_ML_OVERRIDE: - handleTestUsedBicarbVolumeMLOverrideRequest( message ); - break; - #ifndef _RELEASE_ case MSG_ID_DG_GET_SW_CONFIG_RECORD: handleGetDGSoftwareConfigRecord( message ); @@ -1412,6 +1408,10 @@ handleTestRunModeFillForCalibrationCheck( message ); break; + case MSG_ID_DG_MODE_FILL_ENABLE_CHEMS_TEST: + handleTestEnableModeFillChemsTest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r00b244580f01f3cbd1b7d2d5a14ee61675bf4642 -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 00b244580f01f3cbd1b7d2d5a14ee61675bf4642) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -1987,7 +1987,55 @@ sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, status ); } +/*********************************************************************//** + * @brief + * The sendDGInstitutionalValuesRequestToHD function handles sending the + * request to the DG institutional values from HD + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ +void sendDGInstitutionalValuesRequestToHD( void ) +{ + MESSAGE_T msg; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_REQUEST; + msg.hdr.payloadLen = 0; + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_HD, ACK_REQUIRED ); +} + +/*********************************************************************//** + * @brief + * The handleDGInstitutionalValuesResponseFromHDInstitRecord function handles + * receiving DG institutional values from HD institutional record + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleDGInstitutionalValuesResponseFromHDInstitRecord( MESSAGE_T* message ) +{ + BOOL status = FALSE; + + if ( message->hdr.payloadLen == sizeof(DG_INSTITUTIONAL_VALUES_T) ) + { + DG_INSTITUTIONAL_VALUES_T institValues; + + memcpy( &institValues, message->payload, sizeof(DG_INSTITUTIONAL_VALUES_T) ); + setMinRORejectionRatioPCT( institValues.minRORejectionRatioPCT ); + setMinInletWaterConductivityAlarmLimitUSPCM( institValues.minInletWaterCondAlarmLimitUSPCM ); + signalDGInstituionalValuesReceived(); + + status = TRUE; + } + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, status ); +} + // *********************************************************************** // **************** Message Handling Helper Functions ******************** // *********************************************************************** @@ -3875,38 +3923,6 @@ } /*********************************************************************//** - * @brief - * The handleTestUsedAcidVolumeMLOverrideRequest function handles a - * request to override the acid volume. - * @details Inputs: none - * @details Outputs: message handled - * @param message : a pointer to the message to handle - * @return none - *************************************************************************/ -void handleTestUsedAcidVolumeMLOverrideRequest( 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 = testSetUsedAcidVolumeMLOverride( payload.state.f32 ); - } - else - { - result = testResetUsedAcidVolumeMLOverride(); - } - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** * The handleSetFansDutyCycleOverrideRequest function handles a * request to override the fans duty cycle. * @details Inputs: none @@ -3938,38 +3954,6 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } -/*********************************************************************//** - * @brief - * The handleTestUsedBicarbVolumeMLOverrideRequest function handles a - * request to override the used bicarb volume. - * @details Inputs: none - * @details Outputs: message handled - * @param message : a pointer to the message to handle - * @return none - *************************************************************************/ -void handleTestUsedBicarbVolumeMLOverrideRequest( 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 = testSetUsedBicarbVolumeMLOverride( payload.state.f32 ); - } - else - { - result = testResetUsedBicarbVolumeMLOverride(); - } - } - - // Respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - #ifndef _RELEASE_ /*********************************************************************//** * @brief @@ -5238,4 +5222,27 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The handleTestEnableModeFillChemsTest function handles a request + * to enable the mode fill chemicals test. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestEnableModeFillChemsTest( MESSAGE_T* message ) +{ + BOOL result = FALSE; + + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + result = testSetEnableTestChemsCondValuesStatus(); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -re6c60e07b450ec8d58e87bf13d45f96efab54d8b -r75c1e08603496809a6554b7540c9b78a66cb3733 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision e6c60e07b450ec8d58e87bf13d45f96efab54d8b) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 75c1e08603496809a6554b7540c9b78a66cb3733) @@ -201,6 +201,12 @@ // MSG_ID_DG_START_STOP_NOCTURNAL_HEAT_DISINFECT void handleStartStopDGPassiveCoolHeatDisifnect( MESSAGE_T* message ); +// MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_REQUEST +void sendDGInstitutionalValuesRequestToHD( void ); + +// MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_RESPONSE +void handleDGInstitutionalValuesResponseFromHDInstitRecord( MESSAGE_T* message ); + // *********** public test support message functions ********** // MSG_TESTER_LOG_IN @@ -400,12 +406,6 @@ // MSG_ID_DG_SET_FANS_RPM_ALARM_START_TIME_OFFSET void handleTestFansRPMAlarmStartTimeOffsetRequest( MESSAGE_T *message ); -// MSG_ID_DG_USED_ACID_VOLUME_ML_OVERRIDE -void handleTestUsedAcidVolumeMLOverrideRequest(MESSAGE_T *message); - -// MSG_ID_DG_USED_BICARB_VOLUME_ML_OVERRIDE -void handleTestUsedBicarbVolumeMLOverrideRequest(MESSAGE_T *message); - // MSG_ID_DG_FANS_DUTY_CYCLE_OVERRIDE void handleSetFansDutyCycleOverrideRequest( MESSAGE_T *message ); @@ -542,6 +542,9 @@ // MSG_ID_DG_RUN_MODE_FILL_FOR_CAL_CHECK void handleTestRunModeFillForCalibrationCheck( MESSAGE_T* message ); +// MSG_ID_DG_MODE_FILL_ENABLE_CHEMS_TEST +void handleTestEnableModeFillChemsTest( MESSAGE_T* message ); + /**@}*/ #endif