Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -ra14bc308c72272ce0275d263cf010c90d8a37355 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision a14bc308c72272ce0275d263cf010c90d8a37355) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -17,7 +17,6 @@ #include // Used for mathematical operations -//#include "DDDefs.h" #include "FpgaDD.h" #include "Heaters.h" #include "Level.h" @@ -78,12 +77,11 @@ F32 targetTempC; ///< Heater target temperature. HEATERS_STATE_T state; ///< Heater state. BOOL startHeaterSignal; ///< Heater start indication flag. - BOOL isHeaterOn; ///< Heater on/off status flag. + BOOL heaterOnState; ///< Heater on/off status flag. OVERRIDE_F32_T dutyCycle; ///< Heater duty cycle. F32 targetFlowLPM; ///< Heater target flow in L/min to calculate the duty cycle. F32 nomTargetFlowLPM; ///< Heater nominal target flow in L/min. BOOL hasTargetTempChanged; ///< Heater target temperature change flag indicator. - F32 calculatedTemperatureC; ///< Heater calculated temperature. U32 controlIntervalCounter; ///< Heater control interval counter. BOOL isThisFirstControl; ///< Heater is this first control interval. F32 prevDiaTargetFlowLPM; ///< Heater previous target dialysate flow in L/min. @@ -96,11 +94,9 @@ // ********** private function prototypes ********** static HEATERS_STATE_T handleHeaterStateOff( DD_HEATERS_T heater ); -static HEATERS_STATE_T handleHeaterStatePrimaryRampToTarget( void ); -static HEATERS_STATE_T handleHeaterStatePrimaryControlToTarget( void ); +static HEATERS_STATE_T handleHeaterStateRampToTarget( DD_HEATERS_T heater ); +static HEATERS_STATE_T handleHeaterStateControlToTarget( DD_HEATERS_T heater ); static HEATERS_STATE_T handleHeaterStateControlToDisinfectTarget( DD_HEATERS_T heater ); -static HEATERS_STATE_T handleHeaterStateTrimmerRampToTarget( void ); -static HEATERS_STATE_T handleHeaterStateTrimmerControlToTarget( void ); static void setHeaterDutyCycle( DD_HEATERS_T heater ); static F32 getHeaterDutyCycle( DD_HEATERS_T heater ); @@ -120,16 +116,16 @@ DD_HEATERS_T heater; dataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - for ( heater = DD_PRIMARY_HEATER; heater < NUM_OF_DD_HEATERS; heater++ ) + for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { heatersStatus[ heater ].targetTempC = 0.0F; heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; heatersStatus[ heater ].startHeaterSignal = FALSE; - heatersStatus[ heater ].isHeaterOn = FALSE; + heatersStatus[ heater ].heaterOnState = FALSE; heatersStatus[ heater ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ heater ].dutyCycle.ovData = HEATERS_MIN_DUTY_CYCLE; heatersStatus[ heater ].dutyCycle.ovInitData = HEATERS_MIN_DUTY_CYCLE; - heatersStatus[ heater ].dutyCycle.override = 0; + heatersStatus[ heater ].dutyCycle.override = OVERRIDE_RESET; heatersStatus[ heater ].targetFlowLPM = 0.0F; heatersStatus[ heater ].nomTargetFlowLPM = 0.0F; heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -216,7 +212,7 @@ *************************************************************************/ BOOL isHeaterOn( DD_HEATERS_T heater ) { - return heatersStatus[ heater ].isHeaterOn; + return heatersStatus[ heater ].heaterOnState; } /*********************************************************************//** @@ -263,7 +259,12 @@ if( heater < NUM_OF_DD_HEATERS ) { heatersStatus[ heater ].startHeaterSignal = FALSE; - heatersStatus[ heater ].isHeaterOn = FALSE; + heatersStatus[ heater ].heaterOnState = FALSE; + heatersStatus[ heater ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; + + // update duty cycle + setHeaterDutyCycle( heater ); } else { @@ -273,63 +274,50 @@ /*********************************************************************//** * @brief - * The execHeaters function executes the heaters state machine. + * The execHeatersControl function executes the heaters state machine. * @details \b Inputs: heaterStatus * @details \b Outputs: heaterStatus * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid heater * executive state found. * @return none *************************************************************************/ -void execHeaters( void ) +void execHeatersControl( void ) { DD_HEATERS_T heater; - HEATERS_STATE_T state; - for ( heater = DD_PRIMARY_HEATER; heater < NUM_OF_DD_HEATERS; heater++ ) + for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { - state = heatersStatus[ heater ].state; + // Check if the heater is requested to be off + if ( FALSE == heatersStatus[ heater ].heaterOnState ) + { + // stop the heater + stopHeater( heater ); + } - switch( state ) + switch( heatersStatus[ heater ].state ) { case HEATER_EXEC_STATE_OFF: heatersStatus[ heater ].state = handleHeaterStateOff( heater ); break; - case HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET: - heatersStatus[ heater ].state = handleHeaterStatePrimaryRampToTarget(); + case HEATER_EXEC_STATE_RAMP_TO_TARGET: + heatersStatus[ heater ].state = handleHeaterStateRampToTarget( heater ); break; - case HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET: - heatersStatus[ heater ].state = handleHeaterStatePrimaryControlToTarget(); + case HEATER_EXEC_STATE_CONTROL_TO_TARGET: + heatersStatus[ heater ].state = handleHeaterStateControlToTarget( heater ); 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 ); - heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_INVALID_EXEC_STATE, heater ); break; } - - // Check if the heater is requested to be off - if ( FALSE == heatersStatus[ heater ].isHeaterOn ) - { - heatersStatus[ heater ].dutyCycle.data = HEATERS_MIN_DUTY_CYCLE; - setHeaterDutyCycle( heater ); - heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; - } } } @@ -348,37 +336,37 @@ { DD_HEATERS_T heater; - for ( heater = DD_PRIMARY_HEATER; heater < NUM_OF_DD_HEATERS; heater++ ) + for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { // Check if the heater is on and if it is, check the level sensor status - if ( TRUE == heatersStatus[ heater ].isHeaterOn ) + if ( TRUE == heatersStatus[ heater ].heaterOnState ) { ALARM_ID_T alarm; BOOL isLevelLow = FALSE; - if ( DD_PRIMARY_HEATER == heater ) + switch ( heater ) { - alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_PRIMARY_HEATER_IS_ON; - isLevelLow = ( ( getLevelStatus( FLOATER_1 ) != 0 )? FALSE : TRUE ); + case DD_PRIMARY_HEATER: + alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_PRIMARY_HEATER_IS_ON; + isLevelLow = ( ( getLevelStatus( FLOATER_1 ) != 0 )? FALSE : TRUE ); + break; + + case DD_TRIMMER_HEATER: + alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_TRIMMER_HEATER_IS_ON; + isLevelLow = ( ( getLevelStatus( SPENT_DIALYSATE_LEVEL ) != 0 )? FALSE : TRUE ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, heater ) + break; } - else - { - alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_TRIMMER_HEATER_IS_ON; - isLevelLow = ( ( getLevelStatus( SPENT_DIALYSATE_LEVEL ) != 0 )? FALSE : TRUE ); - } checkPersistentAlarm( alarm, isLevelLow, 0.0F, 0.0F ); } else { - if ( DD_PRIMARY_HEATER == heater ) - { - checkPersistentAlarm( ALARM_ID_DD_FLUID_TOO_LOW_WHILE_PRIMARY_HEATER_IS_ON, FALSE, 0.0F, 0.0F ); - } - else - { - checkPersistentAlarm( ALARM_ID_DD_FLUID_TOO_LOW_WHILE_TRIMMER_HEATER_IS_ON, FALSE, 0.0F, 0.0F ); - } + checkPersistentAlarm( ALARM_ID_DD_FLUID_TOO_LOW_WHILE_PRIMARY_HEATER_IS_ON, FALSE, 0.0F, 0.0F ); + checkPersistentAlarm( ALARM_ID_DD_FLUID_TOO_LOW_WHILE_TRIMMER_HEATER_IS_ON, FALSE, 0.0F, 0.0F ); } } @@ -404,71 +392,85 @@ if ( TRUE == heatersStatus[ heater ].startHeaterSignal ) { - heatersStatus[ heater ].isHeaterOn = TRUE; + heatersStatus[ heater ].heaterOnState = TRUE; heatersStatus[ heater ].startHeaterSignal = FALSE; - // Depending on which heater is called, go to different states - state = ( DD_PRIMARY_HEATER == heater ? HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET : HEATER_EXEC_STATE_TRIMMER_RAMP_TO_TARGET ); + // proceed to ramp state + state = HEATER_EXEC_STATE_RAMP_TO_TARGET; } return state; } /*********************************************************************//** * @brief - * The handleHeaterStatePrimaryRampToTarget function handles the primary heaters' + * The handleHeaterStateRampToTarget function handles the given heaters' * control while they are ramping to target temperature. * @details \b Inputs: heaterStatus * @details \b Outputs: heaterStatus + * @param heater: The heater Id to handle the ramping up to target temp. * @return next state of the state machine *************************************************************************/ -static HEATERS_STATE_T handleHeaterStatePrimaryRampToTarget( void ) +static HEATERS_STATE_T handleHeaterStateRampToTarget( DD_HEATERS_T heater ) { - HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_RAMP_TO_TARGET; - DD_HEATERS_T heater = DD_PRIMARY_HEATER; + HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; F32 dutyCycle = 0.0F; DD_OP_MODE_T opMode = getCurrentOperationMode(); if ( DD_MODE_HEAT != opMode ) { - // TODO : Calculate the initial duty cycle - dutyCycle = ( ( heatersStatus[ heater ].targetTempC / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; + dutyCycle = ( ( heatersStatus[ heater ].targetTempC / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; } else { // TODO : Calculate required duty cycle - state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; + state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; } - // Update the calculated target temperature and duty cycle - heatersStatus[ DD_PRIMARY_HEATER ].calculatedTemperatureC = heatersStatus[ heater ].targetTempC; - heatersStatus[ DD_PRIMARY_HEATER ].dutyCycle.data = dutyCycle; + // Update the duty cycle + heatersStatus[ heater ].dutyCycle.data = dutyCycle; setHeaterDutyCycle( heater ); return state; } /*********************************************************************//** * @brief - * The handleHeaterStatePrimaryControlToTarget function handles the primary + * The handleHeaterStateControlToTarget function handles the given * heaters' control to target while the heater is targeting to reach to temperature. * @details \b Inputs: heaterStatus * @details \b Outputs: heaterStatus + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid heater ID passed + * @param heater: The heater Id to handle the control to target state * @return next state of the state machine *************************************************************************/ -static HEATERS_STATE_T handleHeaterStatePrimaryControlToTarget( void ) +static HEATERS_STATE_T handleHeaterStateControlToTarget( DD_HEATERS_T heater ) { - HEATERS_STATE_T state = HEATER_EXEC_STATE_PRIMARY_CONTROL_TO_TARGET; - DD_HEATERS_T heater = DD_PRIMARY_HEATER; - F32 measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_HYDRAULICS_PRIMARY_HEATER); + HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; F32 targetTemperature = heatersStatus[ heater ].targetTempC; + F32 measuredTemperature = 0.0F; F32 dutyCycle = 0.0F; if( ++heatersStatus[ heater ].controlIntervalCounter > PRIMARY_HEATER_CONTROL_INTERVAL_COUNT ) { - dutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, targetTemperature, measuredTemperature ); + switch ( heater ) + { + case DD_PRIMARY_HEATER: + measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_HYDRAULICS_PRIMARY_HEATER ); + dutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, targetTemperature, measuredTemperature ); + break; - heatersStatus[ heater ].calculatedTemperatureC = targetTemperature; + case DD_TRIMMER_HEATER: + measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_TRIMMER_HEATER ); + dutyCycle = runPIController( PI_CONTROLLER_ID_TRIMMER_HEATER, targetTemperature, measuredTemperature ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, heater ) + break; + } + heatersStatus[ heater ].hasTargetTempChanged = FALSE; heatersStatus[ heater ].dutyCycle.data = ( dutyCycle * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; heatersStatus[ heater ].controlIntervalCounter = 0; @@ -503,71 +505,6 @@ /*********************************************************************//** * @brief - * The handleHeaterStateTrimmerRampToTarget function handles the trimmer - * heater's ramp to target. - * @details \b Inputs: heaterStatus - * @details \b 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; - DD_HEATERS_T heater = DD_TRIMMER_HEATER; - F32 dutyCycle = 0.0F; - DD_OP_MODE_T opMode = getCurrentOperationMode(); - - if ( DD_MODE_HEAT != opMode ) - { - // TODO : Calculate the initial duty cycle - dutyCycle = ( ( heatersStatus[ heater ].targetTempC / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; - } - else - { - // TODO : Calculate required duty cycle - state = HEATER_EXEC_STATE_CONTROL_TO_DISINFECT_TARGET; - } - - // Update the calculated target temperature and duty cycle - heatersStatus[ DD_TRIMMER_HEATER ].calculatedTemperatureC = heatersStatus[ heater ].targetTempC; - heatersStatus[ DD_TRIMMER_HEATER ].dutyCycle.data = dutyCycle; - setHeaterDutyCycle( heater ); - - return state; -} - -/*********************************************************************//** - * @brief - * The handleHeaterStateTrimmerControlToTarget function handles the trimmer - * heater's control to target state. - * @details \b Inputs: heaterStatus, trimmerHeaterControlCounter - * @details \b Outputs: heaterStatus, trimmerHeaterControlCounter - * @return next state of the state machine - *************************************************************************/ -static HEATERS_STATE_T handleHeaterStateTrimmerControlToTarget( void ) -{ - HEATERS_STATE_T state = HEATER_EXEC_STATE_TRIMMER_CONTROL_TO_TARGET; - DD_HEATERS_T heater = DD_TRIMMER_HEATER; - F32 measuredTemperature = getTemperatureValue( (U32)TEMPSENSORS_TRIMMER_HEATER ); - F32 targetTemperature = heatersStatus[ heater ].targetTempC; - F32 dutyCycle = 0.0F; - - if( ++heatersStatus[ heater ].controlIntervalCounter > TRIMMER_HEATER_CONTROL_INTERVAL_COUNT ) - { - dutyCycle = runPIController( PI_CONTROLLER_ID_PRIMARY_HEATER, targetTemperature, measuredTemperature ); - - heatersStatus[ heater ].calculatedTemperatureC = targetTemperature; - heatersStatus[ heater ].hasTargetTempChanged = FALSE; - heatersStatus[ heater ].dutyCycle.data = ( dutyCycle * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; - heatersStatus[ heater ].controlIntervalCounter = 0; - - setHeaterDutyCycle( heater ); - } - - return state; -} - -/*********************************************************************//** - * @brief * The setHeaterDutyCycle function sets the duty cycle of a heater. * @details \b Inputs: dutyCycle * @details \b Outputs: FPGA heater control @@ -676,8 +613,6 @@ data.trimmerTargetTemp = heatersStatus[ DD_TRIMMER_HEATER ].targetTempC; data.primaryHeaterState = heatersStatus[ DD_PRIMARY_HEATER ].state; data.trimmerHeaterState = heatersStatus[ DD_TRIMMER_HEATER ].state; - data.primaryCalcTargetTemp = heatersStatus[ DD_PRIMARY_HEATER ].calculatedTemperatureC; - data.trimmerCalcCurrentTemp = heatersStatus[ DD_TRIMMER_HEATER ].calculatedTemperatureC; data.primaryControlCounter = heatersStatus[ DD_PRIMARY_HEATER ].controlIntervalCounter; data.trimmerControlCounter = heatersStatus[ DD_TRIMMER_HEATER ].controlIntervalCounter; @@ -712,55 +647,19 @@ /*********************************************************************//** * @brief - * The testSetHeaterDutyCycleOverride function overrides the specified heater's + * The testHeaterDutyCycleOverride function overrides the specified heater's * duty cycle. * @details \b Inputs: heatersStatus * @details \b Outputs: heatersStatus + * @param message Override message from Dialin which includes an ID of + * the heater to override and the duty cyle of the heater. * @return TRUE if the override was successful otherwise FALSE *************************************************************************/ -BOOL testSetHeaterDutyCycleOverride( U32 heater, F32 value ) +BOOL testHeaterDutyCycleOverride( MESSAGE_T *message ) { - BOOL result = FALSE; + BOOL result = f32ArrayOverride( message, &heatersStatus[0].dutyCycle, NUM_OF_DD_HEATERS - 1 ); - if ( TRUE == isTestingActivated() ) - { - if ( ( value >= HEATERS_MIN_DUTY_CYCLE ) && ( value <= HEATERS_MAX_DUTY_CYCLE ) ) - { - result = TRUE; - heatersStatus[ (DD_HEATERS_T)heater ].dutyCycle.ovData = ( value * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; - heatersStatus[ (DD_HEATERS_T)heater ].dutyCycle.override = OVERRIDE_KEY; - - if ( TRUE == heatersStatus[ (DD_HEATERS_T)heater ].isHeaterOn ) - { - setHeaterDutyCycle( (DD_HEATERS_T)heater ); - } - } - } - return result; } -/*********************************************************************//** - * @brief - * The testResetHeaterDutyCycleOverride function resets the heater's - * duty cycle overridden value. - * @details \b Inputs: heatersStatus - * @details \b Outputs: heatersStatus - * @return TRUE if the reset was successful otherwise, FALSE - *************************************************************************/ -BOOL testResetHeaterDutyCycleOverride( U32 heater ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - heatersStatus[ (DD_HEATERS_T)heater ].dutyCycle.override = OVERRIDE_RESET; - heatersStatus[ (DD_HEATERS_T)heater ].dutyCycle.ovData = heatersStatus[ (DD_HEATERS_T)heater ].dutyCycle.ovInitData; - setHeaterDutyCycle( (DD_HEATERS_T)heater ); - } - - return result; -} - /**@}*/