Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r03e051ef654a1bff100da02483645c4e9d0b7a30 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -111,7 +111,7 @@ static U32 drainControlTimerCounter = 0; ///< Determines when to perform control on drain pump. static BOOL hasClosedLoopBeenRequested = FALSE; ///< Closed loop pump control flag. -static U32 currentDrainPumpRPM = 0; ///< Current drain pump RPM from feedback. +static OVERRIDE_U32_T drainPumpMeasuredRPM = { 0, 0, 0, 0 }; ///< Measured drain pump RPM from feedback. static BOOL signalNewRPMRequest = FALSE; ///< Signal flag the indicates there is a new RPM request. static DRAIN_PUMP_STATE_T pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; ///< Delayed (pending) drain pump command. @@ -148,8 +148,7 @@ signalNewRPMRequest = FALSE; // Initialize the drain pump PI controller - initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, - DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, + initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_MAX_DAC ); // Initialize the persistent alarm for open loop RPM out of range @@ -290,10 +289,9 @@ /*********************************************************************//** * @brief * The signalDrainPumpHardStop function stops the Drain pump immediately. - * @details Inputs: targetDrainPumpSpeed, drainPumpState, drainPumpControlMode, - * hasClosedLoopBeenRequested, drainControlTimerCounter + * @details Inputs: none * @details Outputs: targetDrainPumpSpeed, drainPumpState, drainPumpControlMode, - * hasClosedLoopBeenRequested, drainControlTimerCounter + * hasClosedLoopBeenRequested, drainControlTimerCounter, isRMPNonZeroInClosedLoop * @return none *************************************************************************/ void signalDrainPumpHardStop( void ) @@ -324,12 +322,12 @@ if ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ) { - currentDrainPumpRPM = 0; + drainPumpMeasuredRPM.data = 0; } else { // Convert speed ADC to RPM - currentDrainPumpRPM = CONVERSION_COEFF / getFPGADrainPumpSpeed(); + drainPumpMeasuredRPM.data = CONVERSION_COEFF / getFPGADrainPumpSpeed(); } #ifndef IGNORE_DRAIN_PUMP_MONITOR @@ -339,20 +337,20 @@ if ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) { // Using abs since the read RPM can be above or below the target - U32 rpmDiff = abs( getTargetDrainPumpRPM() - currentDrainPumpRPM ); + U32 rpmDiff = abs( getDrainPumpTargetRPM() - getDrainPumpMeasuredRPM() ); // Check if RPM is out of range BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, currentDrainPumpRPM, MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); } // Check if the pump is in off state and the RPM is greater than the minimum RPM if ( DRAIN_PUMP_OFF_STATE == drainPumpState ) { - BOOL isRPMTooHigh = currentDrainPumpRPM > MIN_DRAIN_PUMP_RPM; + BOOL isRPMTooHigh = ( getDrainPumpMeasuredRPM() > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, currentDrainPumpRPM, MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); // If the off fault alarm has become active, trigger the safety shutdown if ( isAlarmActive( ALARM_ID_DRAIN_PUMP_OFF_FAULT ) ) @@ -391,7 +389,7 @@ } else if ( DRAIN_PUMP_OPEN_LOOP_STATE == pendingDrainPumpCmd ) { - drainPumpDAC = (U32)( pendingDrainPumpCmdTarget * RPM_2_DAC_SLOPE - RPM_2_DAC_INTERCEPT + FLOAT_TO_INT_ROUNDUP_OFFSET ); + drainPumpDAC = (U32)( pendingDrainPumpCmdTarget * RPM_2_DAC_SLOPE - RPM_2_DAC_INTERCEPT + FLOAT_TO_INT_ROUNDUP_OFFSET ); targetDrainPumpRPM = (U32)pendingDrainPumpCmdTarget; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; @@ -451,26 +449,46 @@ /*********************************************************************//** * @brief - * The getTargetDrainPumpRPM function gets the current target drain pump + * The getDrainPumpTargetRPM function gets the current target drain pump * RPM. * @details Inputs: targetDrainPumpRPM * @details Outputs: none * @return the current target drain pump RPM. *************************************************************************/ -U32 getTargetDrainPumpRPM( void ) +U32 getDrainPumpTargetRPM( void ) { return targetDrainPumpRPM; } /*********************************************************************//** * @brief + * The getDrainPumpMeasuredRPM function returns the RPM read from the drain + * pump RPM sensor. + * @details Inputs: drainPumpMeasuredRPM + * @details Outputs: none + * @return drain pump RPM + *************************************************************************/ +U32 getDrainPumpMeasuredRPM( void ) +{ + U32 rpm = drainPumpMeasuredRPM.data; + + if ( OVERRIDE_KEY == drainPumpMeasuredRPM.override ) + { + rpm = drainPumpMeasuredRPM.ovData; + } + + return rpm; +} + +/*********************************************************************//** + * @brief * The getTargetDrainPumpOutletPressure function gets the current target * drain pump delta pressure. * @details Inputs: targetDrainPumpOutletPressure * @details Outputs: none * @return the current target drain pump outlet pressure. *************************************************************************/ -F32 getTargetDrainPumpOutletPressure( void ) +F32 getDrainPumpTargetOutletPressure( void ) { return targetDrainPumpOutletPressure; } @@ -514,7 +532,7 @@ // If the target drain pump speed was not 0 and the control mode // is open loop, set the drain pump to open loop - if ( ( getTargetDrainPumpRPM() > 0 ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) ) + if ( ( getDrainPumpTargetRPM() > 0 ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) ) { // Set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); @@ -562,7 +580,7 @@ if ( ++drainControlTimerCounter >= DRP_CONTROL_INTERVAL ) { F32 outletDrainPressure = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); - F32 dac = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, getTargetDrainPumpOutletPressure(), outletDrainPressure ); + F32 dac = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, getDrainPumpTargetOutletPressure(), outletDrainPressure ); // The PI controller sends the DAC out and it is rounded to the nearest offset and is fed to the FPGA drainPumpDACSet = (U32)( dac + FLOAT_TO_INT_ROUNDUP_OFFSET ); @@ -571,13 +589,6 @@ drainControlTimerCounter = 0; } - // Check if the RPM is 0, and if it is turn off the pump - if ( 0 == getTargetDrainPumpRPM() ) - { - state = DRAIN_PUMP_OFF_STATE; - signalDrainPumpHardStop(); - } - return state; } @@ -592,14 +603,8 @@ { DRAIN_PUMP_STATE_T state = DRAIN_PUMP_OPEN_LOOP_STATE; - // Check if the RPM is 0, then turn off the pump - if ( 0 == getTargetDrainPumpRPM() ) - { - state = DRAIN_PUMP_OFF_STATE; - signalDrainPumpHardStop(); - } // If there is a signal for a new RPM, change to the new RPM - else if ( TRUE == signalNewRPMRequest ) + if ( TRUE == signalNewRPMRequest ) { // Set drain pump DAC drainPumpDACSet = drainPumpDAC; @@ -642,10 +647,11 @@ DRAIN_PUMP_DATA_T drainPumpData; // Populate the data structure for publication - drainPumpData.rpmSetPoint = getTargetDrainPumpRPM(); + drainPumpData.rpmSetPoint = getDrainPumpTargetRPM(); drainPumpData.pumpDACSet = drainPumpDACSet; drainPumpData.drainPumpState = (U32)drainPumpState; - drainPumpData.drainPumpRPM = currentDrainPumpRPM; + drainPumpData.drainPumpRPM = getDrainPumpMeasuredRPM(); + drainPumpData.trgtOutletPrsr = targetDrainPumpOutletPressure; broadcastDrainPumpData( &drainPumpData ); @@ -753,10 +759,15 @@ if ( TRUE == isTestingActivated() ) { - if ( ( 0 == value ) || ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) + if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) { result = setDrainPumpTargetRPM( value ); } + + if ( 0 == value ) + { + signalDrainPumpHardStop(); + } } return result; @@ -778,7 +789,7 @@ if ( TRUE == isTestingActivated() ) { // Check if delta pressure is in range - if ( value >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE && value <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) + if ( ( value >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE ) && ( value <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) ) { result = setDrainPumpTargetOutletPressure( value ); } @@ -787,4 +798,56 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetDrainPumpMeasuredRPMOverride function overrides the drain pump + * measured RPM data. + * @details Inputs: none + * @details Outputs: drainPumpMeasuredRPM + * @param value override drain pump measured data + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDrainPumpMeasuredRPMOverride( U32 value ) +{ + BOOL status = FALSE; + + // Check if the requested drain pump RPM is within range + if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) + { + // Check if the user is logged in + if ( TRUE == isTestingActivated() ) + { + drainPumpMeasuredRPM.ovData = value; + drainPumpMeasuredRPM.override = OVERRIDE_KEY; + drainPumpMeasuredRPM.ovInitData = drainPumpMeasuredRPM.data; + status = TRUE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The testResetDrainPumpMeasuredRPMOverride function resets the drain pump + * measured RPM data. + * @details Inputs: none + * @details Outputs: drainPumpMeasuredRPM + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDrainPumpMeasuredRPMOverride( void ) +{ + BOOL status = FALSE; + + // Check if the user is logged in + if ( TRUE == isTestingActivated() ) + { + drainPumpMeasuredRPM.ovData = drainPumpMeasuredRPM.ovInitData; + drainPumpMeasuredRPM.override = OVERRIDE_RESET; + status = TRUE; + } + + return status; +} + /**@}*/ Index: firmware/App/Controllers/DrainPump.h =================================================================== diff -u -r24e8fcb5744724be72ea26bebd95ec594c2c26fe -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 24e8fcb5744724be72ea26bebd95ec594c2c26fe) +++ firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -43,6 +43,7 @@ U32 pumpDACSet; ///< Drain pump DAC set value U32 drainPumpState; ///< Drain pump state machine state U32 drainPumpRPM; ///< Drain pump current RPM + F32 trgtOutletPrsr; ///< Drain pump target outlet pressure } DRAIN_PUMP_DATA_T; // ********** public function prototypes ********** @@ -61,8 +62,10 @@ void signalDrainPumpHardStop( void ); -U32 getTargetDrainPumpRPM( void ); -F32 getTargetDrainPumpOutletPressure( void ); +U32 getDrainPumpTargetRPM( void ); +U32 getDrainPumpMeasuredRPM( void ); +F32 getDrainPumpTargetOutletPressure( void ); + BOOL isDrainPumpOn( void ); F32 getFlushLineVolume( void ); @@ -74,6 +77,9 @@ BOOL testSetTargetDrainPumpOutletPressure( F32 value ); +BOOL testSetDrainPumpMeasuredRPMOverride( U32 value ); +BOOL testResetDrainPumpMeasuredRPMOverride( void ); + /**@}*/ #endif Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r03e051ef654a1bff100da02483645c4e9d0b7a30 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -43,14 +43,10 @@ // ********** private definitions ********** -#define HEATERS_MAX_DUTY_CYCLE 1.00 ///< Main primary heater (heater A) max duty cycle (100%). -#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Primary and trimmer heaters minimum duty cycle (0.00%). +#define HEATERS_MAX_DUTY_CYCLE 1.00 ///< Heaters max duty cycle (100%). +#define HEATERS_MIN_DUTY_CYCLE 0.00 ///< Heaters minimum duty cycle (0.00%). +#define HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE 0.6 ///< Heaters minimum duty cycle during heat disinfect. -#define PRIMARY_HEATER_P_COEFFICIENT 0.05 ///< Primary heaters proportional coefficient. - -#define TRIMMER_HEATER_P_COEFFICIENT 0.02 // TODO remove ///< Trimmer heater proportional coefficient. -#define TRIMMER_HEATER_I_COEFFICIENT 0.001 // TODO remove ///< Trimmer heater integral coefficient. - #define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. #define MINIMUM_TARGET_TEMPERATURE 10.0 ///< Minimum allowed target temperature for the heaters. @@ -80,11 +76,11 @@ typedef enum Heaters_Exec_States { HEATER_EXEC_STATE_OFF = 0, ///< Heater exec state off. - HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET, ///< Heater exec state ramp to target. - HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET, ///< Heater exec state control to target. + HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET, ///< Heater exec state primary ramp to target. + HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET, ///< Heater exec state primary control to target. HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET, ///< Heater exec state control to disinfect (heat or chemical) target. - HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET, - HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET, + HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET, ///< Heater exec state trimmer ramp to target. + HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET, ///< Heater exec state trimmer control to target. NUM_OF_HEATERS_STATE, ///< Number of heaters state. } HEATERS_STATE_T; @@ -93,7 +89,6 @@ { F32 targetTemp; ///< Heater target temperature. HEATERS_STATE_T state; ///< Heater state. - U32 controlTimerCounter; // TODO remove? Maybe use in heat disinfect ///< Heater control timer counter. BOOL startHeaterSignal; ///< Heater start indication flag. BOOL isHeaterOn; ///< Heater on/off status flag. F32 dutycycle; ///< Heater duty cycle. @@ -117,12 +112,14 @@ // ********** private function prototypes ********** static HEATERS_STATE_T handleHeaterStateOff( DG_HEATERS_T heater ); -static HEATERS_STATE_T handleHeaterStateRampToTarget( DG_HEATERS_T heater ); -static HEATERS_STATE_T handleHeaterStateControlToTarget( DG_HEATERS_T heater ); +static HEATERS_STATE_T handleHeaterStatePrimaryRampToTarget( void ); +static HEATERS_STATE_T handleHeaterStatePrimaryControlToTarget( void ); static HEATERS_STATE_T handleHeaterStateControlToDisinfectTarget( DG_HEATERS_T heater ); +static HEATERS_STATE_T handleHeaterStateTrimmerRampToTarget( void ); +static HEATERS_STATE_T handleHeaterStateTrimmerControlToTarget( void ); static void setHeaterDutyCycle( DG_HEATERS_T heater, F32 pwm ); -static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow ); +static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow, BOOL checkEfficiency ); static BOOL haveHeaterControlConditionsChanged( DG_HEATERS_T heater ); static void setMainPrimaryHeaterPWM( F32 pwm ); @@ -150,7 +147,6 @@ for ( heater = DG_PRIMARY_HEATER; heater < NUM_OF_DG_HEATERS; heater++ ) { - heatersStatus[ heater ].controlTimerCounter = 0; heatersStatus[ heater ].startHeaterSignal = FALSE; heatersStatus[ heater ].tempOutOfRangeTimer = 0; heatersStatus[ heater ].isHeaterTempOutOfRange = FALSE; @@ -271,17 +267,25 @@ break; case HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET: - heatersStatus[ heater ].state = handleHeaterStateRampToTarget( heater ); + heatersStatus[ heater ].state = handleHeaterStatePrimaryRampToTarget(); break; case HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET: - heatersStatus[ heater ].state = handleHeaterStateControlToTarget( heater ); + heatersStatus[ heater ].state = handleHeaterStatePrimaryControlToTarget(); break; case HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET: heatersStatus[ heater ].state = handleHeaterStateControlToDisinfectTarget( heater ); break; + case HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET: + heatersStatus[ heater ].state = handleHeaterStateTrimmerRampToTarget(); + break; + + case HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET: + heatersStatus[ heater ].state = handleHeaterStateTrimmerControlToTarget(); + break; + default: // The heater is in an unknown state. Turn it off and switch to not running state stopHeater( heater ); @@ -404,8 +408,23 @@ publishHeatersData(); } + /*********************************************************************//** * @brief + * The resetHeatersEfficiency function resets the heaters efficiency upon + * the start of a treatment. + * @details Inputs: none + * @details Outputs: heaterStatus + * @return none + *************************************************************************/ +void resetHeatersEfficiency( void ) +{ + heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = 1.0; + heatersStatus[ DG_TRIMMER_HEATER ].heaterEfficiency = 1.0; +} + +/*********************************************************************//** + * @brief * The handleHeaterStateOff function handles the heater not running state. * @details Inputs: heaterStatus * @details Outputs: heaterStatus @@ -421,51 +440,51 @@ heatersStatus[ heater ].isHeaterOn = TRUE; heatersStatus[ heater ].startHeaterSignal = FALSE; - // Turn on the heater - state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; + // Depending on which heater is called, go to different states + state = ( heater == DG_PRIMARY_HEATER ? HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET : HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET ); } return state; } /*********************************************************************//** * @brief - * The handleHeaterStateRampToTarget function handles the heaters' control - * while they are ramping to target temperature. + * The handleHeaterStatePrimaryRampToTarget function handles the primary heaters' + * control while they are ramping to target temperature. * @details Inputs: heaterStatus * @details Outputs: heaterStatus - * @param heater: The heater Id that its on state is handled * @return next state of the state machine *************************************************************************/ -static HEATERS_STATE_T handleHeaterStateRampToTarget( DG_HEATERS_T heater ) +static HEATERS_STATE_T handleHeaterStatePrimaryRampToTarget( void ) { HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; + DG_HEATERS_T heater = DG_PRIMARY_HEATER; F32 inletTemperature = getTemperatureValue( (U32)TEMPSENSORS_HEAT_DISINFECT ); F32 targetFlow = 0.0; F32 dutyCycle = 0.0; F32 targetTemperature = heatersStatus[ heater ].targetTemp; if ( DG_MODE_FILL == getCurrentOperationMode() ) { - // Get the previous fill's average flow rate - targetFlow = getAvgFillFlowRate(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); + // If the previous average fill flow rate is 0, use the nominal target RO flow from the RO pump + targetFlow = ( getAvgFillFlowRate() - 0.0 > NEARLY_ZERO ? getAvgFillFlowRate() : getTargetROPumpFlowRate() ); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, TRUE ); state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_GENE == getCurrentOperationMode() ) || ( DG_MODE_DRAI == getCurrentOperationMode() ) ) { targetTemperature += DELTA_TEMPERATURE_TIME_COSNTANT_C; // Use target flow rate during Idle and drain targetFlow = getTargetROPumpFlowRate(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; } else if ( ( DG_MODE_HEAT == getCurrentOperationMode() ) || ( DG_MODE_CHEM == getCurrentOperationMode() ) ) { // If the mode is any of the disinfects, especially heat, use the target flow rate instead of the avg. flow // Most of the times the heater should be running at 100% duty cycle since the target temperature is 81 C targetFlow = getTargetROPumpFlowRate(); - dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow ); + dutyCycle = calculatePrimaryHeaterDutyCycle( targetTemperature, inletTemperature, targetFlow, FALSE ); state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; } @@ -476,16 +495,16 @@ /*********************************************************************//** * @brief - * The handleHeaterStateControlToTarget function handles the heaters' control - * to target while the heater is targeting to reach to temperature. + * The handleHeaterStatePrimaryControlToTarget function handles the primary + * heaters' control to target while the heater is targeting to reach to temperature. * @details Inputs: heaterStatus * @details Outputs: heaterStatus - * @param heater: The heater Id that its on state is handled * @return next state of the state machine *************************************************************************/ -static HEATERS_STATE_T handleHeaterStateControlToTarget( DG_HEATERS_T heater ) +static HEATERS_STATE_T handleHeaterStatePrimaryControlToTarget( void ) { HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; + DG_HEATERS_T heater = DG_PRIMARY_HEATER; // TODO do we need any control to maintain the temperature? @@ -532,14 +551,47 @@ { // Set the flag to true for the next run heatersStatus[ heater ].hasTargetBeenReached = TRUE; - setHeaterDutyCycle( heater, HEATERS_MIN_DUTY_CYCLE ); + // The primary heater are not turned off but it is set to a minimum duty cycle so the temperature is kept + // above the target + setHeaterDutyCycle( heater, HEATERS_MIN_HEAT_DISINFECT_DUTY_CYCLE ); } return state; } /*********************************************************************//** * @brief + * The handleHeaterStateTrimmerRampToTarget function handles the trimmer + * heater's ramp to target. + * @details Inputs: heaterStatus + * @details Outputs: heaterStatus + * @return next state of the state machine + *************************************************************************/ +static HEATERS_STATE_T handleHeaterStateTrimmerRampToTarget( void ) +{ + HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET; + + return state; +} + +/*********************************************************************//** + * @brief + * The handleHeaterStateTrimmerControlToTarget function handles the trimmer + * heater's control to target. + * @details Inputs: heaterStatus + * @details Outputs: heaterStatus + * @return next state of the state machine + *************************************************************************/ +static HEATERS_STATE_T handleHeaterStateTrimmerControlToTarget( void ) +{ + HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET; + + + return state; +} + +/*********************************************************************//** + * @brief * The setHeaterDutyCycle function sets the duty cycle of a heater. * @details Inputs: none * @details Outputs: none @@ -573,27 +625,31 @@ * @param flow current flow * @return calculated duty cycle *************************************************************************/ -static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow ) +static F32 calculatePrimaryHeaterDutyCycle( F32 targetTemperature, F32 currentTemperature, F32 flow, BOOL checkEfficiency ) { // Get the primary heater's efficiency and the last fill temperature from the ModeFill - F32 heaterEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency; - F32 lastFillTemperature = getLastFillTemperature(); + F32 heaterEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency; - // If the last fill temperature > target temperature, it means the primary heater overshot the duty cycle - // so with its efficiency is toned down for the next fill cycle - // If the heater undershot the duty cycle, the efficiency increases the duty cycle for the next fill cycle - if ( lastFillTemperature - targetTemperature > MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) + if ( TRUE == checkEfficiency ) { - heaterEfficiency -= ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; - } - else if ( lastFillTemperature - targetTemperature <= MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) - { - heaterEfficiency += ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; - } + F32 lastFillTemperature = getLastFillTemperature(); - // Update the heaters efficiency - heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = heaterEfficiency; + // If the last fill temperature > target temperature, it means the primary heater overshot the duty cycle + // so with its efficiency is toned down for the next fill cycle + // If the heater undershoots the duty cycle, the efficiency increases the duty cycle for the next fill cycle + if ( lastFillTemperature - targetTemperature > MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) + { + heaterEfficiency -= ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } + else if ( lastFillTemperature - targetTemperature <= MAXIMUM_ALLOWED_TARGET_TEMPERATURE_DEVIATION_C ) + { + heaterEfficiency += ( lastFillTemperature - targetTemperature ) * PRIMARY_HEATER_DUTY_CYCLE_PER_TEMPERATURE_C; + } + // Update the heaters efficiency + heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency = heaterEfficiency; + } + // Duty cycle = ( 69.73 * flow rate * deltaT / primary heater maximum power ) ^ 1/2 // Multiply the duty cycle to the heater efficiency F32 dutyCycle = sqrt( ( WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * @@ -697,6 +753,7 @@ data.trimmerTargetTemp = heatersStatus[ DG_TRIMMER_HEATER ].targetTemp; data.primaryHeaterState = heatersStatus[ DG_PRIMARY_HEATER ].state; data.trimmerHeaterState = heatersStatus[ DG_TRIMMER_HEATER ].state; + data.primaryEfficiency = heatersStatus[ DG_PRIMARY_HEATER ].heaterEfficiency * 100; broadcastData( MSG_ID_DG_HEATERS_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( HEATERS_DATA_T ) ); Index: firmware/App/Controllers/Heaters.h =================================================================== diff -u -rd332a26f463cc5d209be77e562952f70775cf913 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision d332a26f463cc5d209be77e562952f70775cf913) +++ firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -66,6 +66,8 @@ F32 trimmerTargetTemp; ///< Trimmer heater target temperature U32 primaryHeaterState; ///< Primary heater state U32 trimmerHeaterState; ///< Trimmer heater state + + F32 primaryEfficiency; } HEATERS_DATA_T; #pragma pack(pop) @@ -87,6 +89,8 @@ void execHeatersMonitor( void ); +void resetHeatersEfficiency( void ); + BOOL testSetHeatersPublishIntervalOverride( U32 value ); BOOL testResetHeatersPublishIntervalOverride( void ); Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r03e051ef654a1bff100da02483645c4e9d0b7a30 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -905,7 +905,7 @@ if ( TRUE == isTestingActivated() ) { // The flow rate and pressure must be in range - if ( flow <= MAX_RO_FLOWRATE_LPM && flow >= MIN_RO_FLOWRATE_LPM ) + if ( ( flow <= MAX_RO_FLOWRATE_LPM ) && ( flow >= MIN_RO_FLOWRATE_LPM ) ) { result = setROPumpTargetFlowRate( flow, MAX_ALLOWED_PRESSURE_PSI ); } Index: firmware/App/DGCommon.h =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/DGCommon.h (.../DGCommon.h) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -43,7 +43,7 @@ #define ALARMS_DEBUG 1 // #define HEATERS_DEBUG 1 // #define PRESSURES_DEBUG 1 - #define IGNORE_DRAIN_PUMP_MONITOR 1 + // #define IGNORE_DRAIN_PUMP_MONITOR 1 // #define IGNORE_HEATERS_MONITOR 1 #define IGNORE_RO_PUMP_MONITOR 1 #define DISABLE_RO_RATIO_CHECK 1 Index: firmware/App/Drivers/SafetyShutdown.c =================================================================== diff -u -r53f4c6476728fdbfc76147062e66e8bb21d30841 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Drivers/SafetyShutdown.c (.../SafetyShutdown.c) (revision 53f4c6476728fdbfc76147062e66e8bb21d30841) +++ firmware/App/Drivers/SafetyShutdown.c (.../SafetyShutdown.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -62,15 +62,17 @@ * @brief * The initSafetyShutdown function initializes the safety shutdown module. * @details Inputs: none - * @details Outputs: Safety shutdown module signal output set to initial state. + * @details Outputs: safetyShutdownActivated, safetyShutdownOverrideResetState, + * safetyShutdownSelfTestState, safetyShutdownSelfTestStatus, + * safetyShutdownSelfTestTimerCount * @return none *************************************************************************/ void initSafetyShutdown( void ) { - safetyShutdownActivated = FALSE; + safetyShutdownActivated = FALSE; safetyShutdownOverrideResetState = FALSE; - safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_START; - safetyShutdownSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_START; + safetyShutdownSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; safetyShutdownSelfTestTimerCount = 0; CLR_SAFETY_SHUTDOWN(); } Index: firmware/App/Drivers/SafetyShutdown.h =================================================================== diff -u -r53f4c6476728fdbfc76147062e66e8bb21d30841 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Drivers/SafetyShutdown.h (.../SafetyShutdown.h) (revision 53f4c6476728fdbfc76147062e66e8bb21d30841) +++ firmware/App/Drivers/SafetyShutdown.h (.../SafetyShutdown.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -26,7 +26,14 @@ * * @addtogroup SafetyShutdown * @{ - */ + */ + +// ********** public definitions ********** +/// Safety shutdown broadcast data +typedef struct +{ + U32 isSafetyShutdownActivated; ///< Is safety shutdown active boolean flag +} DG_SAFETY_SHUTDOWN_DATA_T; // ********** public function prototypes ********** Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -821,7 +821,7 @@ { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already @@ -1294,7 +1294,7 @@ signalDrainPumpHardStop(); signalROPumpHardStop(); - if ( 0 == getTargetDrainPumpRPM() ) + if ( 0 == getDrainPumpTargetRPM() ) { // De-energize all the valves that are not in the path anymore // and wait for the RO membrane to be cooled down. @@ -1508,7 +1508,7 @@ { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already @@ -1600,7 +1600,7 @@ { rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 2 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -raf0faf02f1bd7bffcce083e9b52988a01c343d8e -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision af0faf02f1bd7bffcce083e9b52988a01c343d8e) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -26,6 +26,7 @@ #include "SystemComm.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" +#include "Timers.h" #include "Valves.h" /** @@ -35,38 +36,42 @@ // ********** private definitions ********** -#define TARGET_DRAIN_PUMP_RPM 2100 ///< Target drain pump speed (in RPM). -#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 2 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. -/// Time period to wait after drain complete and before taring load cells. -#define DRAIN_EMPTY_TARE_WAIT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define TARGET_DRAIN_PUMP_RPM 2400 ///< Target drain pump speed (in RPM). +#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 2 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. -#define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. -#define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. +#define DRAIN_EMPTY_TARE_WAIT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Time period to wait after drain complete and before taring load cells. -#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. +#define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. +#define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. +#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. + +#define DIALYSATE_DRAIN_TIME_OUT ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Dialysate drain time out. + // ********** 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 DG_DRAIN_STATE_T drainState; ///< Currently active drain state. +static U32 drainEmptyTareTimerCtr; ///< Timer counter for delay between drain complete and load cell tare. +static U32 dialysateDrainStartTime; ///< Dialysate drain start time. // ********** private function prototypes ********** +static DG_DRAIN_STATE_T handleDrainStateStart( void ); +static DG_DRAIN_STATE_T handleDrainStateDrain( void ); +static DG_DRAIN_STATE_T handleDrainStateTare( void ); -static DG_DRAIN_STATE_T handleDrainState( void ); -static DG_DRAIN_STATE_T handleTareState( void ); - /*********************************************************************//** * @brief * The initDrainMode function initializes the drain mode module. * @details Inputs: none - * @details Outputs: drainState + * @details Outputs: drainState, drainEmptyTareTimerCtr, dialysateDrainStartTime * @return none *************************************************************************/ void initDrainMode( void ) { - drainState = DG_DRAIN_STATE_START; - drainEmptyTareTimerCtr = 0; + drainState = DG_DRAIN_STATE_START; + drainEmptyTareTimerCtr = 0; + dialysateDrainStartTime = 0; } /*********************************************************************//** @@ -125,18 +130,15 @@ switch ( drainState ) { case DG_DRAIN_STATE_START: - if ( TRUE == isDrainPumpOn() ) - { - drainState = DG_DRAIN_STATE_DRAIN; - } + drainState = handleDrainStateStart(); break; case DG_DRAIN_STATE_DRAIN: - drainState = handleDrainState(); + drainState = handleDrainStateDrain(); break; case DG_DRAIN_STATE_TARE: - drainState = handleTareState(); + drainState = handleDrainStateTare(); break; default: @@ -150,13 +152,34 @@ /*********************************************************************//** * @brief - * The handleDrainState function handles the drain state of the drain mode - * state machine. + * The handleDrainStateStart function handles the drain start state of + * the drain mode state machine. * @details Inputs: none + * @details Outputs: dialysateDrainStartTime + * @return the next state + *************************************************************************/ +static DG_DRAIN_STATE_T handleDrainStateStart( void ) +{ + DG_DRAIN_STATE_T state = DG_DRAIN_STATE_START; + + if ( TRUE == isDrainPumpOn() ) + { + dialysateDrainStartTime = getMSTimerCount(); + state = DG_DRAIN_STATE_DRAIN; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleDrainStateDrain function handles the drain state of the drain + * mode state machine. + * @details Inputs: none * @details Outputs: none * @return the next state *************************************************************************/ -static DG_DRAIN_STATE_T handleDrainState( void ) +static DG_DRAIN_STATE_T handleDrainStateDrain( void ) { DG_DRAIN_STATE_T result = DG_DRAIN_STATE_DRAIN; DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); @@ -185,18 +208,24 @@ } } + // Drain timed out raise the alarm + if ( TRUE == didTimeout( dialysateDrainStartTime, DIALYSATE_DRAIN_TIME_OUT ) ) + { + activateAlarmNoData( ALARM_ID_DG_DIALYSATE_DRAIN_TIME_OUT ); + } + return result; } /*********************************************************************//** * @brief - * The handleTareState function handles the tare state of the drain mode + * The handleDrainStateTare function handles the tare state of the drain mode * state machine. * @details Inputs: drainEmptyTareTimerCtr * @details Outputs: drainEmptyTareTimerCtr * @return the next state *************************************************************************/ -static DG_DRAIN_STATE_T handleTareState( void ) +static DG_DRAIN_STATE_T handleDrainStateTare( void ) { DG_DRAIN_STATE_T result = DG_DRAIN_STATE_TARE; DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r03e051ef654a1bff100da02483645c4e9d0b7a30 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -21,6 +21,8 @@ #include "Heaters.h" #include "LoadCell.h" #include "ModeFill.h" +#include "NVDataMgmtDGRecords.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Pressures.h" @@ -106,7 +108,7 @@ static BOOL isWaterQualityGood( void ); static BOOL checkDialysateTemperature( void ); static void handleDialysateMixing( F32 measuredROFlowRate_mL_min ); -static void getAvgFillFlowRateFromRTCRAM( void ); +static void setFillInfoToRTCRAM( void ); /*********************************************************************//** * @brief @@ -126,7 +128,10 @@ dialysateConductivityTotal = 0.0; conductivitySampleCount = 0; concentratePumpPrimeCount = 0; - fillStatus.fillFlowRateAverage = 0.79; // TODO change this to 0 once RTC RAM is implemented + // Get the heaters info form the NV data management + DG_HEATERS_RECORD_T heaterInfo = getHeatersInfoReocrd(); + // If the data in the NV data management was not initialized properly, set it to 0 otherwise, set the average flow rate + fillStatus.fillFlowRateAverage = ( heaterInfo.averageFillFlow - 0.0 < NEARLY_ZERO ? 0.0 : heaterInfo.averageFillFlow ); fillStatus.fillFlowRateRunningSum = 0.0; fillStatus.fillSampleCounter = 0; fillStatus.fillTemperatureRunningSum = 0.0; @@ -183,7 +188,7 @@ checkInletWaterTemperature(); checkInletPressure(); checkRORejectionRatio(); - getAvgFillFlowRateFromRTCRAM(); + setFillInfoToRTCRAM(); // TODO: Check for open straw door status and alarm if closed // Check if run out of time to fill the reservoir @@ -572,6 +577,9 @@ // Get the last fill temperature before leaving to Generation Idle fillStatus.fillLastTemperature = getTemperatureValue( (U32)TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + // Write the latest fill data into the RTC RAM for heaters control + setFillInfoToRTCRAM(); + requestNewOperationMode( DG_MODE_GENE ); } @@ -657,9 +665,21 @@ #endif } -static void getAvgFillFlowRateFromRTCRAM( void ) +/*********************************************************************//** + * @brief + * The setFillInfoToRTCRAM function writes the fill information to the RTC + * RAM at the end of each fill. This information is used for dialysate temperature + * control. + * @details Inputs: fillStatus.fillFlowRateAverage + * @details Outputs: none + * @return none + *************************************************************************/ +static void setFillInfoToRTCRAM( void ) { + DG_HEATERS_RECORD_T record; + record.averageFillFlow = fillStatus.fillFlowRateAverage; + setHeatersInfoRecord( (U08*)&record ); } Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -r03e051ef654a1bff100da02483645c4e9d0b7a30 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 03e051ef654a1bff100da02483645c4e9d0b7a30) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -38,7 +38,6 @@ U32 execFillMode( void ); // execute the fill mode state machine (call from OperationModes) F32 getAvgFillFlowRate( void ); -void setAvgFillFlowRateToRTCRAM( void ); // TODO do we need this? F32 getAvgFillTemperature( void ); // TODO do we need this? Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -42,7 +42,7 @@ #define FLUSH_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Mode flush data publish interval in counts. #define RO_PUMP_TARGET_FLOW_RATE_LPM 0.8 ///< RO pump target flow rate during flush/fill in L/min. #define RO_PUMP_MAX_PRESSURE_PSI 130 ///< Maximum RO pump pressure during flush/fill states in psi. -#define DRAIN_PUMP_TARGET_RPM 2200 ///< Drain pump target RPM during drain. +#define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. // Drain R1 & R2 states defines #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. @@ -624,7 +624,7 @@ { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r60ec2f1256b02ee0a6d4346877494ce1bda55ab2 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 60ec2f1256b02ee0a6d4346877494ce1bda55ab2) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -49,7 +49,7 @@ #define MAX_START_STATE_TEMP_SENSORS_DIFF_C 3.0 ///< Max start state TDi and TRo difference tolerance in C. // Drain R1 & R2 states defines -#define DRAIN_PUMP_TARGET_RPM 2200 ///< Drain pump target RPM during drain. +#define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. #define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. @@ -829,7 +829,7 @@ { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already @@ -1518,7 +1518,7 @@ { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - U32 drainPumpRPM = getTargetDrainPumpRPM(); + U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rbd9f7ebe27d5fbdc893d04c9925f1990e873edfa -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision bd9f7ebe27d5fbdc893d04c9925f1990e873edfa) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -69,21 +69,25 @@ * @brief * The initStandbyMode function initializes the standby mode module. * @details Inputs: none - * @details Outputs: Standby mode module initialized + * @details Outputs: standbyState, stopSampleWaterRequest, startSampleWaterRequest, + * flushFilterRequest, endSampleWaterRequest, waterSampleStartTime, + * filterFlushStartTime, filterFlushPublishTimerCounter, pendingStartDGRequest * @return none *************************************************************************/ void initStandbyMode( void ) { - standbyState = DG_STANDBY_MODE_STATE_START; - stopSampleWaterRequest = FALSE; - startSampleWaterRequest = FALSE; - flushFilterRequest = FALSE; - endSampleWaterRequest = FALSE; - - waterSampleStartTime = 0; - filterFlushStartTime = 0; + standbyState = DG_STANDBY_MODE_STATE_START; + stopSampleWaterRequest = FALSE; + startSampleWaterRequest = FALSE; + flushFilterRequest = FALSE; + endSampleWaterRequest = FALSE; + waterSampleStartTime = 0; + filterFlushStartTime = 0; filterFlushPublishTimerCounter = 0; - pendingStartDGRequest = FALSE; + pendingStartDGRequest = FALSE; + + // Reset the heaters efficiency for another treatment + resetHeatersEfficiency(); } /*********************************************************************//** Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -1096,8 +1096,8 @@ handleTestROPumpDataBroadcastIntervalOverrideRequest( message ); break; - case MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE: - handleTestDrainPumpRPMOverrideRequest( message ); + case MSG_ID_DRAIN_PUMP_SET_RPM: + handleTestSetDrainPumpRPM( message ); break; case MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: @@ -1284,6 +1284,10 @@ handleStopDGRTCClock( message ); break; + case MSG_ID_DG_DRAIN_PUMP_MEASURED_RPM_OVERRIDE: + handleSetDrainPumpMeasuredRPMOverrideRequest( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -2161,14 +2161,14 @@ /*********************************************************************//** * @brief - * The handleTestDrainPumpRPMOverrideRequest function handles a request to - * override the drain pump speed set point (in RPM). + * The handleTestSetDrainPumpRPM function handles a request to set the drain + * pump speed set point (in RPM). * @details Inputs: none * @details Outputs: message handled * @param message a pointer to the message to handle * @return none *************************************************************************/ -void handleTestDrainPumpRPMOverrideRequest( MESSAGE_T *message ) +void handleTestSetDrainPumpRPM( MESSAGE_T *message ) { BOOL result = FALSE; @@ -3615,6 +3615,38 @@ /*********************************************************************//** * @brief +* The handleSetDrainPumpMeasuredRPMOverrideRequest function handles a request +* to override the drain pump measured RPM. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleSetDrainPumpMeasuredRPMOverrideRequest( 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 = testSetDrainPumpMeasuredRPMOverride( payload.state.u32 ); + } + else + { + result = testResetDrainPumpMeasuredRPMOverride(); + } + } + + // 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. * @details Inputs: none Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r8a42ba4060bf15e63d291fa23df6fcd5434beab4 -r26f63d0260a3c35277e3e6dbca3573c253775318 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 8a42ba4060bf15e63d291fa23df6fcd5434beab4) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 26f63d0260a3c35277e3e6dbca3573c253775318) @@ -252,8 +252,8 @@ // MSG_ID_RO_PUMP_SEND_INTERVAL_OVERRIDE: void handleTestROPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); -// MSG_ID_DRAIN_PUMP_SET_RPM_OVERRIDE -void handleTestDrainPumpRPMOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DRAIN_PUMP_SET_RPM +void handleTestSetDrainPumpRPM( MESSAGE_T *message ); // MSG_ID_DRAIN_PUMP_SEND_INTERVAL_OVERRIDE: void handleTestDrainPumpDataBroadcastIntervalOverrideRequest( MESSAGE_T *message ); @@ -396,6 +396,9 @@ // MSG_ID_DG_STOP_RTC_CLOCK void handleStopDGRTCClock( MESSAGE_T * message ); +// MSG_ID_DG_DRAIN_PUMP_MEASURED_RPM_OVERRIDE +void handleSetDrainPumpMeasuredRPMOverrideRequest( MESSAGE_T *message ); + /**@}*/ #endif