Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -187,6 +187,7 @@ { if( heater < NUM_OF_DG_HEATERS ) { +#ifndef DISABLE_HEATERS_AND_TEMPS // Assume the target temperature has not changed heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -197,6 +198,7 @@ heatersStatus[ heater ].hasTargetTempChanged = TRUE; // TODO alarm if temperature if out of range or just reject? } +#endif } else { @@ -228,13 +230,16 @@ { BOOL status = FALSE; + if( heater < NUM_OF_DG_HEATERS ) { +#ifndef DISABLE_HEATERS_AND_TEMPS if ( TRUE == heatersStatus[ heater ].hasTargetTempChanged ) { status = TRUE; heatersStatus[ heater ].startHeaterSignal = TRUE; } +#endif } else { @@ -327,9 +332,11 @@ if ( TRUE == heaterCmdPtr->startHeater ) { +#ifndef DISABLE_TRIMMER_HEATER if ( ( MINIMUM_TARGET_TEMPERATURE <= heaterCmdPtr->targetTemp ) && ( heaterCmdPtr->targetTemp <= MAXIMUM_TARGET_TEMPERATURE ) ) { cmdResponse.rejected = FALSE; + #ifndef DISABLE_HEATERS_AND_TEMPS heatersStatus[ DG_TRIMMER_HEATER ].targetTemp = heaterCmdPtr->targetTemp; heatersStatus[ DG_TRIMMER_HEATER ].startHeaterSignal = TRUE; @@ -339,6 +346,7 @@ { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; } +#endif } else { @@ -361,7 +369,7 @@ *************************************************************************/ void execHeatersMonitor( void ) { - /*DG_HEATERS_T heater; + DG_HEATERS_T heater; #ifndef IGNORE_HEATERS_MONITOR checkPrimaryHeaterTempSensors(); @@ -404,7 +412,7 @@ heatersStatus[ heater ].heaterOnWithNoFlowTimer = getMSTimerCount(); } } - }*/ + } // TODO un-comment the heaters voltage //monitorHeatersVoltage(); @@ -756,12 +764,12 @@ if ( trimmerHeaterInternalTemp > HEATERS_MAX_ALLOWED_INTERNAL_TEMPERATURE_C ) { isTempOut = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_INTERNAL_TEMP_OUT_OF_RANGE, trimmerHeaterInternalTemp ); + //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_INTERNAL_TEMP_OUT_OF_RANGE, trimmerHeaterInternalTemp ); } else if ( trimmerHeaterColdJunctionTemp > HEATERS_MAX_ALLOWED_COLD_JUNCTION_TEMPERATURE_C ) { isTempOut = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_CJ_TEMP_OUT_OF_RANGE, trimmerHeaterColdJunctionTemp ); + //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TRIMMER_HEATER_CJ_TEMP_OUT_OF_RANGE, trimmerHeaterColdJunctionTemp ); } // If it is above the range for the first time, stop the trimmer heater Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -319,12 +319,16 @@ roControlTimerCounter = 0; isROPumpOn = FALSE; targetROPumpMaxPressure = 0; + pendingROPumpCmdMaxPressure = 0.0; + pendingROPumpCmdTargetFlow = 0.0; + pendingROPumpCmdCountDown = 0; resetPIController( PI_CONTROLLER_ID_RO_PUMP_FLOW, MIN_RO_PUMP_DUTY_CYCLE ); } /*********************************************************************//** * @brief - * The execROPumpMonitor function executes the RO pump monitor. + * The execROPumpMonitor function executes the RO pump monitor. The RO flow + * sensor is read, filtered, converted to L/min and calibrated. * @details Inputs: measuredFlowReadingsSum, flowFilterCounter, * measuredROFlowRateLPM, measuredROFlowRateLPM, roPumpState, * flowOutOfRangeCounter, roPumpControlMode @@ -360,20 +364,20 @@ // Read flow at the control set if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE ) { - F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); + F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER ); // Convert flow sensor period to L/min + // Apply calibration to flow sensor reading measuredROFlowRateLPM.data = pow(flow, 4) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].fourthOrderCoeff + pow(flow, 3) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].thirdOrderCoeff + pow(flow, 2) * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].secondOrderCoeff + - flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + + flow * flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].gain + flowSensorsCalRecord.flowSensors[ CAL_DATA_RO_PUMP_FLOW_SENSOR ].offset; - // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that - // the flow is 0. - if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) - { - measuredROFlowRateLPM.data = 0.0; - } + // If the flow is less than a certain value, FPGA will return 0xFFFF meaning that the flow is 0. + if ( FLOW_SENSOR_ZERO_READING == roFlowReading ) + { + measuredROFlowRateLPM.data = 0.0; + } measuredFlowReadingsSum = 0; flowFilterCounter = 0; Index: firmware/App/DGCommon.h =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/DGCommon.h (.../DGCommon.h) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -25,7 +25,7 @@ #define DG_VERSION_MAJOR 0 #define DG_VERSION_MINOR 6 #define DG_VERSION_MICRO 0 -#define DG_VERSION_BUILD 14 +#define DG_VERSION_BUILD 70 // ********** build switches ********** @@ -34,7 +34,7 @@ // TODO: Removed debug build flags when release build is ready // #define BOARD_WITH_NO_HARDWARE 1 // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing -// #define DISABLE_HEATERS_AND_TEMPS 1 +// #define DISABLE_HEATERS_AND_TEMPS 1 // #define DISABLE_ACCELS 1 // #define SKIP_POST 1 #define SKIP_CAL_CHECK 1 @@ -48,16 +48,19 @@ #define IGNORE_RO_PUMP_MONITOR 1 #define DISABLE_RO_RATIO_CHECK 1 // #define DISABLE_COND_SENSOR_CHECK 1 -// #define DISABLE_WATER_QUALITY_CHECK 1 + #define DISABLE_WATER_QUALITY_CHECK 1 #define DISABLE_RTC_CONFIG 1 #define THD_USING_TRO_CONNECTOR 1 + #define DISABLE_FLOW_CHECK_IN_FILL 1 #define IGNORE_CONC_PUMP_IN_HEAT_DISINFECT 1 // Turn these flags on to disable dialysate mixing #define DISABLE_DIALYSATE_CHECK 1 #define DISABLE_MIXING 1 //#define DISABLE_FLOW_CONTROL_TREATMENT 1 + #define DISABLE_TRIMMER_HEATER 1 + #include #include #endif Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "DrainPump.h" #include "Heaters.h" @@ -46,15 +47,23 @@ #define DELAY_RES_DRAIN_VALVE_MS 1000 ///< Delay reservoir drain valve open by 1 second. #define DELAY_DRAIN_PUMP_MS 2000 ///< Delay drain pump on by 2 seconds. +/// Time period to wait for concentrate lines to rinse. +#define RINSE_CONCENTRATE_LINES_WAIT ( 25 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +/// Reserver the concentrate speed to rinse out concentrate lines. +#define RINSE_SPEED ( ( CONCENTRATE_PUMP_MAX_SPEED - 3.0 ) * -1.0 ) + // ********** private data ********** static DG_DRAIN_STATE_T drainState; ///< Currently active drain state. static U32 drainEmptyTareTimerCtr; ///< Timer counter for delay between drain complete and load cell tare. +static BOOL rinseConcentrateLines; ///< Flag indicates to rinse concentrate lines. +static U32 rinseConcentrateLinesTimerCtr; ///< Timer counter for rinsing concentrate lines. // ********** private function prototypes ********** static DG_DRAIN_STATE_T handleDrainState( void ); static DG_DRAIN_STATE_T handleTareState( void ); +static DG_DRAIN_STATE_T handleRinseState( void ); /*********************************************************************//** * @brief @@ -67,6 +76,8 @@ { drainState = DG_DRAIN_STATE_START; drainEmptyTareTimerCtr = 0; + rinseConcentrateLines = FALSE; + rinseConcentrateLinesTimerCtr = 0; } /*********************************************************************//** @@ -127,6 +138,7 @@ case DG_DRAIN_STATE_START: if ( TRUE == isDrainPumpOn() ) { + resetReservoirsLowestWeight(); drainState = DG_DRAIN_STATE_DRAIN; } break; @@ -139,6 +151,10 @@ drainState = handleTareState(); break; + case DG_DRAIN_STATE_RINSE: + drainState = handleRinseState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_MODE_INVALID_EXEC_STATE, drainState ) drainState = DG_DRAIN_STATE_START; @@ -150,6 +166,31 @@ /*********************************************************************//** * @brief + * The getCurrentDrainState function returns the current state of the drain mode. + * @details Inputs: drainState + * @details Outputs: none + * @return the current state of drain mode. + *************************************************************************/ +DG_DRAIN_STATE_T getCurrentDrainState( void ) +{ + return drainState; +} + +/*********************************************************************//** + * @brief + * The signalDrainModeRinseConcentrateLines function sets the flag for drain + * mode to rinse concentrate lines. + * @details Inputs: none + * @details Outputs: rinseConcentrateLines + * @return none + *************************************************************************/ +void signalDrainModeRinseConcentrateLines( BOOL rinse ) +{ + rinseConcentrateLines = rinse; +} + +/*********************************************************************//** + * @brief * The handleDrainState function handles the drain state of the drain mode * state machine. * @details Inputs: none @@ -164,7 +205,7 @@ // 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 == hasTargetDrainVolumeBeenReached( inactiveReservoir, DRAIN_WEIGHT_UNCHANGE_TIMEOUT ) ) { - setDrainPumpTargetRPM( 0 ); + signalDrainPumpHardStop(); if ( DG_RESERVOIR_1 == inactiveReservoir ) { @@ -205,25 +246,52 @@ { drainEmptyTareTimerCtr = 0; tareLoadCellsAtEmpty( inactiveReservoir ); - requestNewOperationMode( DG_MODE_GENE ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); + + if ( TRUE == rinseConcentrateLines ) + { + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, RINSE_SPEED ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, RINSE_SPEED ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + } + rinseConcentrateLinesTimerCtr = 0; + result = DG_DRAIN_STATE_RINSE; } return result; } /*********************************************************************//** * @brief - * The getCurrentDrainState function returns the current state of the drain mode. - * @details Inputs: drainState - * @details Outputs: none - * @return the current state of drain mode. + * The handleRinseState function handles the tare state of the drain mode + * state machine. + * @details Inputs: drainEmptyTareTimerCtr + * @details Outputs: drainEmptyTareTimerCtr + * @return the next state *************************************************************************/ -DG_DRAIN_STATE_T getCurrentDrainState( void ) +static DG_DRAIN_STATE_T handleRinseState( void ) { - return drainState; + DG_DRAIN_STATE_T result = DG_DRAIN_STATE_RINSE; + + if ( TRUE == rinseConcentrateLines ) + { + if ( ++rinseConcentrateLinesTimerCtr > RINSE_CONCENTRATE_LINES_WAIT ) + { + rinseConcentrateLinesTimerCtr = 0; + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + requestNewOperationMode( DG_MODE_GENE ); + } + } + else + { + requestNewOperationMode( DG_MODE_GENE ); + } + + return result; } /**@}*/ Index: firmware/App/Modes/ModeDrain.h =================================================================== diff -u -r24dd186948c13ae8e1ff88c14cc4f478e739ee0b -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeDrain.h (.../ModeDrain.h) (revision 24dd186948c13ae8e1ff88c14cc4f478e739ee0b) +++ firmware/App/Modes/ModeDrain.h (.../ModeDrain.h) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -34,7 +34,7 @@ // ********** public function prototypes ********** void initDrainMode( void ); // initialize this module -void transitionToDrainMode( void ); // prepares for transition to operating parameters mode +U32 transitionToDrainMode( void ); // prepares for transition to operating parameters mode U32 execDrainMode( void ); // execute the drain mode state machine DG_DRAIN_STATE_T getCurrentDrainState( void ); // get the current state of the drain mode. Index: firmware/App/Modes/ModeFault.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -84,6 +84,8 @@ *************************************************************************/ U32 execFaultMode( void ) { + deenergizeActuators(); + // execute current fault state switch ( faultState ) { Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -43,7 +43,7 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define TARGET_RO_FLOW_RATE_L 0.8 ///< Target flow rate for RO pump. -#define DIALYSATE_FILL_TIME_OUT ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. +#define DIALYSATE_FILL_TIME_OUT ( 8 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time out period when reservoir is not filled with correct dialysate. #define EMPTY_BOTTLE_DETECT_PERSISTENT_PERIOD_MS ( 5 * MS_PER_SECOND ) ///< Persistent period for empty bottle detect. ///< Persistent time interval for concentrate pumps prime. #define CONCENTRATE_PUMP_PRIME_INTERVAL ( 3 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) @@ -318,15 +318,16 @@ DG_FILL_MODE_STATE_T result = DG_FILL_MODE_STATE_BICARB_PUMP_CHECK; DG_BICARB_CONCENTRATES_RECORD_T bicarb = getBicarbConcentrateCalRecord(); F32 const measuredROFlowRate_mL_min = getMeasuredROFlowRate() * ML_PER_LITER; - F32 const bicarbPumpFlowRate_mL_min = measuredROFlowRate_mL_min * bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio + + F32 bicarbPumpFlowRate_mL_min = measuredROFlowRate_mL_min * bicarb.bicarbConcentrate[ CAL_DATA_BICARB_CONCENTRATE_1 ].bicarbConcMixRatio + CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN; - #ifndef DISABLE_DIALYSATE_CHECK F32 const bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); #else - F32 const bicarbConductivity = MIN_BICARB_CONCENTRATE_CONDUCTIVITY; + F32 const bicarbConductivity = MAX_BICARB_CONCENTRATE_CONDUCTIVITY; #endif + bicarbPumpFlowRate_mL_min = MIN( bicarbPumpFlowRate_mL_min, CONCENTRATE_PUMP_MAX_SPEED ); + if ( MIN_BICARB_CONCENTRATE_CONDUCTIVITY <= bicarbConductivity ) { // Reduce acid pump speed after reaching minimum conductivity @@ -379,9 +380,11 @@ #ifndef DISABLE_DIALYSATE_CHECK F32 const acidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); #else - F32 const acidConductivity = MIN_ACID_CONCENTRATE_CONDUCTIVITY; + F32 const acidConductivity = MAX_ACID_CONCENTRATE_CONDUCTIVITY; #endif + acidPumpFlowRate_mL_min = MIN( acidPumpFlowRate_mL_min, CONCENTRATE_PUMP_MAX_SPEED ); + if ( MIN_ACID_CONCENTRATE_CONDUCTIVITY <= acidConductivity ) { // Reduce acid pump speed after reaching minimum conductivity @@ -431,10 +434,12 @@ { // Prime mixing before deliver result to reservoir handleDialysateMixing( measuredROFlowRate_mL_min ); +#ifndef DISABLE_MIXING requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); if ( concentratePumpPrimeCount++ > CONCENTRATE_PUMP_PRIME_INTERVAL ) +#endif { setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); result = DG_FILL_MODE_STATE_DELIVER_DIALYSATE; @@ -514,7 +519,7 @@ result = DG_FILL_MODE_STATE_PAUSED; } #endif - +#ifndef DISABLE_MIXING if ( ( ACID_CONCENTRATION_BOTTLE_VOLUME_ML - getF32OverrideValue( &usedAcidVolume_mL ) ) <= CONCENTRATION_BOTTLE_LOW_VOLUME_ML ) { activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); @@ -524,18 +529,18 @@ { activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); } - +#endif // If we've reached our target fill to volume (by weight), we're done filling - go back to generation idle mode - if ( ( TRUE == hasTargetFillVolumeBeenReached( inactiveReservoir ) ) || ( ( integratedVolume_mL - reservoirBaseWeight ) >= MAX_RESERVOIR_VOLUME_ML ) ) + if ( TRUE == hasTargetFillVolumeBeenReached( inactiveReservoir ) ) { F32 const filledVolume_mL = getReservoirWeight( inactiveReservoir ) - reservoirBaseWeight; F32 const integratedVolumeToLoadCellReadingPercent = fabs( 1 - ( filledVolume_mL / integratedVolume_mL ) ); - F32 const avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; + F32 const avgAcidConductivity = acidConductivityTotal / conductivitySampleCount; // TODO - should we be checking this below? F32 const avgDialysateConductivity = dialysateConductivityTotal / conductivitySampleCount; if ( integratedVolumeToLoadCellReadingPercent > FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE ) { -#ifndef DISABLE_MIXING +#ifndef DISABLE_FLOW_CHECK_IN_FILL SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_FLOW_METER_CHECK_FAILURE, filledVolume_mL, integratedVolume_mL ); #endif } Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -48,13 +48,13 @@ #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines -#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo it was 2 minutes +#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. // Flush dialysate state defines -#define FLUSH_DIALYSATE_WAIT_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. +#define FLUSH_DIALYSATE_WAIT_TIME_MS ( 1 * 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. // Flush concentrate straws state defines -#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. todo was 3 minutes +#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. #define ACID_PUMP_SPEED_ML_PER_MIN -30.0 ///< Acid pump speed in mL/min. // The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during flush #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6 ///< Bicarb pump speed in mL/min. @@ -302,6 +302,7 @@ // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); + // Set the actuators to drain R1 setValveState( VRD1, VALVE_STATE_OPEN ); @@ -336,7 +337,6 @@ { if ( TRUE == isThisInitialDrain ) { - // Request a tare for reservoir 1 tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); } Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -110,7 +110,6 @@ // the new PWMs for the main and small primary heaters #ifndef DISABLE_FLOW_CONTROL_TREATMENT setROPumpTargetFlowRate( TARGET_FLUSH_LINES_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); - setHeaterTargetTemperature( DG_PRIMARY_HEATER, 39.0 ); // remove this line. It comes form HD this for testing only startHeater( DG_PRIMARY_HEATER ); #endif @@ -141,7 +140,7 @@ { if ( TRUE == didTimeout( hdLostCommStartTime_ms, HD_LOST_COMM_TIMEOUT_MS ) ) { - //requestNewOperationMode( DG_MODE_STAN ); TODO uncomment there is no HD in unit 2 + requestNewOperationMode( DG_MODE_STAN ); } } Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -505,6 +505,9 @@ } else { + tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); + tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); + // Assume reservoir 2 is full and drain it rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -290,15 +290,15 @@ { DG_POST_STATE_T result = postState; - if ( ( SELF_TEST_STATUS_PASSED == testStatus ) || ( SELF_TEST_STATUS_FAILED == testStatus ) ) + if ( ( testStatus == SELF_TEST_STATUS_PASSED ) || ( testStatus == SELF_TEST_STATUS_FAILED ) ) { - BOOL passed = ( SELF_TEST_STATUS_PASSED == testStatus ? TRUE : FALSE ); + BOOL passed = ( testStatus == SELF_TEST_STATUS_PASSED ? TRUE : FALSE ); // Broadcast passed POST result sendPOSTTestResult( (DG_POST_STATE_T)((int)postState), passed ); // Move on to next POST test result = (DG_POST_STATE_T)((int)postState + 1); - if ( SELF_TEST_STATUS_FAILED == testStatus ) + if ( testStatus == SELF_TEST_STATUS_FAILED ) { tempPOSTPassed = FALSE; } Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -rf215311725c002c9b9f2915e3502b89ae6a93c91 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision f215311725c002c9b9f2915e3502b89ae6a93c91) @@ -22,11 +22,11 @@ #include "Accel.h" #include "ConcentratePumps.h" #include "ConductivitySensors.h" -#include "Fans.h" #include "FPGA.h" #include "Heaters.h" #include "ModeFlush.h" #include "ModeGenIdle.h" +#include "ModeInitPOST.h" #include "ModeStandby.h" #include "MsgQueues.h" #include "NVDataMgmt.h" @@ -56,10 +56,22 @@ #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif +#define MAX_MSGS_BLOCKED_FOR_XMIT 8 ///< Maximum number of messages to block transmission for. + +#pragma pack(push,1) +/// Payload record structure for block message transmission request. +typedef struct +{ + U16 blockedMessages[ MAX_MSGS_BLOCKED_FOR_XMIT ]; +} BLOCKED_MSGS_DATA_T; +#pragma pack(pop) + // ********** private data ********** static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. static volatile U16 nextSeqNo = 1; ///< Next sequence number. +/// List of message IDs that are requested not to be transmitted. +static BLOCKED_MSGS_DATA_T blockedMessagesForXmit = { 0, 0, 0, 0, 0, 0, 0, 0 }; // ********** private function prototypes ********** @@ -84,66 +96,89 @@ { BOOL result = FALSE; BOOL error = FALSE; + BOOL blocked = FALSE; U32 msgSize = 0; U32 sizeMod, sizePad; U32 i; U08 crc; U08 data[ MAX_ACK_MSG_SIZE ]; // byte array to populate with message data - // prefix data with message sync byte - data[ msgSize++ ] = MESSAGE_SYNC_BYTE; + // Check to see if tester has requested this message not be transmited + if ( TRUE == isTestingActivated() ) + { + U32 i; + + for ( i = 0; i < MAX_MSGS_BLOCKED_FOR_XMIT; i++ ) + { + if ( msg.hdr.msgID == blockedMessagesForXmit.blockedMessages[ i ] ) + { + blocked = TRUE; + break; + } + } + } + // Serialize and queue message for transmission unless this message is blocked + if ( blocked != TRUE ) + { + // prefix data with message sync byte + data[ msgSize++ ] = MESSAGE_SYNC_BYTE; - // set sequence # and ACK bit (unless this is an ACK to a received message) - if ( msg.hdr.msgID != MSG_ID_ACK ) - { - // thread protect next sequence # access & increment - _disable_IRQ(); - msg.hdr.seqNo = nextSeqNo; - nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); - _enable_IRQ(); - if ( TRUE == ackReq ) + // set sequence # and ACK bit (unless this is an ACK to a received message) + if ( msg.hdr.msgID != MSG_ID_ACK ) { - msg.hdr.seqNo *= -1; + // thread protect next sequence # access & increment + _disable_IRQ(); + msg.hdr.seqNo = nextSeqNo; + nextSeqNo = INC_WRAP( nextSeqNo, MIN_MSG_SEQ_NO, MAX_MSG_SEQ_NO ); + _enable_IRQ(); + if ( TRUE == ackReq ) + { + msg.hdr.seqNo *= -1; + } } - } - // calculate message CRC - crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); + // calculate message CRC + crc = crc8( (U08*)(&msg), sizeof( MESSAGE_HEADER_T ) + msg.hdr.payloadLen ); - // serialize message header data - memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); - msgSize += sizeof( MESSAGE_HEADER_T ); + // serialize message header data + memcpy( &data[ msgSize ], &( msg.hdr ), sizeof( MESSAGE_HEADER_T ) ); + msgSize += sizeof( MESSAGE_HEADER_T ); - // serialize message payload (only used bytes per payloadLen field) - memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); - msgSize += msg.hdr.payloadLen; + // serialize message payload (only used bytes per payloadLen field) + memcpy( &data[ msgSize ], &( msg.payload ), msg.hdr.payloadLen ); + msgSize += msg.hdr.payloadLen; - // add 8-bit CRC - data[ msgSize++ ] = crc; + // add 8-bit CRC + data[ msgSize++ ] = crc; - // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) - sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; - sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); - for ( i = 0; i < sizePad; i++ ) - { - data[ msgSize++ ] = 0; - } + // pad with zero bytes to get length a multiple of CAN_MESSAGE_PAYLOAD_SIZE (8) + sizeMod = msgSize % CAN_MESSAGE_PAYLOAD_SIZE; + sizePad = ( sizeMod == 0 ? 0 : CAN_MESSAGE_PAYLOAD_SIZE - sizeMod ); + for ( i = 0; i < sizePad; i++ ) + { + data[ msgSize++ ] = 0; + } - // if ACK required, add to pending ACK list - if ( TRUE == ackReq ) - { - if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + // if ACK required, add to pending ACK list + if ( TRUE == ackReq ) { - error = TRUE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + if ( FALSE == addMsgToPendingACKList( &msg, buffer, data, msgSize ) ) + { + error = TRUE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL ) + } } - } - if ( FALSE == error ) - { - // add serialized message data to appropriate out-going comm buffer - result = addToCommBuffer( buffer, data, msgSize ); - } + if ( FALSE == error ) + { + // add serialized message data to appropriate out-going comm buffer + result = addToCommBuffer( buffer, data, msgSize ); + } + } + else + { + result = TRUE; // If message blocked, return successful transmission + } return result; } @@ -3230,7 +3265,6 @@ { BOOL status = FALSE; BOOL result = FALSE; - U08* payloadPtr = message->payload; if ( 0 == message->hdr.payloadLen ) { @@ -3555,37 +3589,6 @@ } /*********************************************************************//** - * @brief - * The handleFansRPMOverride function handles a request to override a fans RPM value. - * @details Inputs: none - * @details Outputs: message handled - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleFansRPMOverride( MESSAGE_T *message ) -{ - TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; - BOOL result = FALSE; - - // verify payload length - if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) - { - memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); - if ( FALSE == payload.reset ) - { - result = testSetFanRPMOverride( payload.index, payload.state.f32 ); - } - else - { - result = testResetFanRPMOverride( payload.index ); - } - } - - // respond to request - sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); -} - -/*********************************************************************//** * @brief * The handleStartStopDGChemicalDisinfect function handles a request to start * or stop DG chemical disinfect mode. @@ -3620,4 +3623,31 @@ return result; } +/*********************************************************************//** + * @brief + * The handleTestBlockMessagesRequest function handles a request to + * block transmission of specific message(s). + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestBlockMessagesRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(BLOCKED_MSGS_DATA_T) == message->hdr.payloadLen ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + memcpy( &blockedMessagesForXmit.blockedMessages[0], message->payload, sizeof(BLOCKED_MSGS_DATA_T) ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/