Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -rbbcdba8850dd6f6a53044eca6a5ece611654653a -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision bbcdba8850dd6f6a53044eca6a5ece611654653a) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -47,6 +47,7 @@ #define DIALYSATE_PUMP_CONTROL_STOP 0x00 ///< Dialysate pump control stop pump. #define DIALYSATE_PUMP_FORWARD_DIR 1 ///< Dialysate pump forward direction. reverse direction is not allowed. #define DIALYSATE_PUMP_SPEED_INCREMENT 5.0F ///< Speed increase when controlling dialysate pump to target step speed. +#define ZERO_SPEED 0.0F ///< Zero speed/RPM value. #define DIALYSATE_PUMP_MAX_CURRENT_WHEN_OFF_A 0.1F ///< Dialysate pump maximum current when the pump is off in amps. #define DIALYSATE_PUMP_MAX_CURRENT_A 2.2F ///< Dialysate pump maximum current in amps. @@ -67,10 +68,13 @@ #define DIALYSATE_PUMP_MAX_PRESSURE_PSI 40.0F ///< Maximum dialysate pump pressure in psi. #define DIALYSATE_PUMP_SPEED_ZERO_RPM 0 ///< Dialysate pump zero RPM speed. -#define DIALYSATE_PUMP_P_COEFFICIENT 1.0F ///< P term for dialysate pump delta pressure control. -#define DIALYSATE_PUMP_I_COEFFICIENT 1.0F ///< I term for dialysate pump delta pressure control. +#define FRESH_DIALYSATE_PUMP_P_COEFFICIENT 1.0F ///< P term for fresh dialysate pump delta pressure control. +#define FRESH_DIALYSATE_PUMP_I_COEFFICIENT 0.0F ///< I term for fresh dialysate pump delta pressure control. +#define SPENT_DIALYSATE_PUMP_P_COEFFICIENT 1.0F ///< P term for spent dialysate pump delta pressure control. +#define SPENT_DIALYSATE_PUMP_I_COEFFICIENT 0.0F ///< I term for spent dialysate pump delta pressure control. #define MAX_ALLOWED_RPM_OUT_OF_RANGE 300 ///< Maximum allowed RPM out of range from target RPM in open loop. +#define PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD 20.0F ///< Speed change that alters the state to ramp during control state. #define RPM_OUT_OF_RANGE_TIME_OUT ( 10 * MS_PER_SECOND ) ///< Open loop RPM out of range time out in ms. #define SAFETY_SHUTDOWN_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Dialysate pump safety shutdown activation timeout. @@ -98,7 +102,8 @@ U32 controlTimerCounter; ///< Timer counter to perform control on dialysate pump. DIALYSATE_PUMP_STATE_T dialysatePumpState; ///< Current state of dialysate pump controller state machine. BOOL isDialPumpOn; ///< Flag indicates dialysate pump On or Off state - OVERRIDE_F32_T pumpTargetSpeed; ///< Target dialysate pumps' speed (mL/min). + OVERRIDE_F32_T pumpTargetSpeed; ///< Target dialysate pumps' speed (mL/min).forward direction only, hence positive speed. + F32 prevPumpTargetSpeed; ///< Previous target dialysate pumps' speed (mL/min). F32 currentPumpSpeed; ///< Current controlled dialysate pumps' speed (mL/min). OVERRIDE_F32_T measuredPumpSpeed; ///< Measured dialysate pump speed (mL/min). OVERRIDE_F32_T dialysatePumpMeasuredCurrentA; ///< Measured dialysate pump current feedback. @@ -125,7 +130,6 @@ // ********** private function prototypes ********** static void publishDialysatePumpsData( void ); -static void stopDialysatePump( DIALYSATE_PUMPS_T pumpId ); static DIALYSATE_PUMP_STATE_T handleDialysatePumpControlToTargetState( DIALYSATE_PUMPS_T pumpId ); static BOOL stepDialysatePumpToTargetSpeed( DIALYSATE_PUMPS_T pumpId ); static DIALYSATE_PUMP_STATE_T handleDialysatePumpRampToTargetState( DIALYSATE_PUMPS_T pumpId ); @@ -143,7 +147,7 @@ { DIALYSATE_PUMPS_T pumpId; - dialysatePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + dialysatePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; for ( pumpId = DIALYSATE_PUMPS_FIRST; pumpId < NUM_OF_DIALYSATE_PUMPS; pumpId++ ) { @@ -152,13 +156,22 @@ dialysatePumps[ pumpId ].isDialPumpOn = FALSE; dialysatePumps[ pumpId ].measuredPumpSpeed.data = 0.0F; dialysatePumps[ pumpId ].measuredPumpSpeed.ovInitData = 0.0F; + dialysatePumps[ pumpId ].measuredPumpSpeed.override = OVERRIDE_RESET; + dialysatePumps[ pumpId ].measuredPumpSpeed.ovData = 0.0F; dialysatePumps[ pumpId ].pumpTargetSpeed.data = 0.0F; dialysatePumps[ pumpId ].pumpTargetSpeed.ovInitData = 0.0F; + dialysatePumps[ pumpId ].pumpTargetSpeed.override = OVERRIDE_RESET; + dialysatePumps[ pumpId ].pumpTargetSpeed.ovData = 0.0F; dialysatePumps[ pumpId ].measuredDirection.data = DIALYSATE_PUMP_FORWARD_DIR; dialysatePumps[ pumpId ].measuredDirection.ovInitData = DIALYSATE_PUMP_FORWARD_DIR; + dialysatePumps[ pumpId ].measuredDirection.ovData = DIALYSATE_PUMP_FORWARD_DIR; + dialysatePumps[ pumpId ].measuredDirection.override = OVERRIDE_RESET; dialysatePumps[ pumpId ].dialysatePumpMeasuredCurrentA.data = 0.0F; dialysatePumps[ pumpId ].dialysatePumpMeasuredCurrentA.ovInitData = 0.0F; + dialysatePumps[ pumpId ].dialysatePumpMeasuredCurrentA.ovData = 0.0F; + dialysatePumps[ pumpId ].dialysatePumpMeasuredCurrentA.override = OVERRIDE_RESET; dialysatePumps[ pumpId ].currentPumpSpeed = 0.0F; + dialysatePumps[ pumpId ].prevPumpTargetSpeed = 0.0F; dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; dialysatePumps[ pumpId ].directionErrorCount = 0; dialysatePumps[ pumpId ].lastDirectionErrorCount = 0; @@ -176,11 +189,11 @@ dialysatePumps[SPENT_DIALYSATE_PUMP].pumpTargetPressure.override = OVERRIDE_RESET; // Initialize the fresh dialysate pump PI controller - initializePIController( PI_CONTROLLER_ID_FRESH_DIALYSATE_PUMP, DIALYSATE_PUMP_MIN_PRESSURE_PSI, DIALYSATE_PUMP_P_COEFFICIENT, DIALYSATE_PUMP_I_COEFFICIENT, + initializePIController( PI_CONTROLLER_ID_FRESH_DIALYSATE_PUMP, DIALYSATE_PUMP_MIN_PRESSURE_PSI, FRESH_DIALYSATE_PUMP_P_COEFFICIENT, FRESH_DIALYSATE_PUMP_I_COEFFICIENT, DIALYSATE_PUMP_MIN_PRESSURE_PSI, DIALYSATE_PUMP_MAX_PRESSURE_PSI ); // Initialize spent dialysate pump PI controller - initializePIController( PI_CONTROLLER_ID_SPENT_DIALYSATE_PUMP, DIALYSATE_PUMP_MIN_PRESSURE_PSI, DIALYSATE_PUMP_P_COEFFICIENT, DIALYSATE_PUMP_I_COEFFICIENT, + initializePIController( PI_CONTROLLER_ID_SPENT_DIALYSATE_PUMP, DIALYSATE_PUMP_MIN_PRESSURE_PSI, SPENT_DIALYSATE_PUMP_P_COEFFICIENT, SPENT_DIALYSATE_PUMP_I_COEFFICIENT, DIALYSATE_PUMP_MIN_PRESSURE_PSI, DIALYSATE_PUMP_MAX_PRESSURE_PSI ); // Initialize the persistent alarms for fresh dialysate pump @@ -230,6 +243,18 @@ dialysatePumps[ pumpId ].pumpTargetSpeed.data = MAX_DIALYSATE_PUMP_RPM; } + //handle target speed update when pump is running + if ( DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE == dialysatePumps[ pumpId ].dialysatePumpState ) + { + F32 diffSpeed = fabs( getDialysatePumpTargetSpeed( pumpId ) - dialysatePumps[ pumpId ].prevPumpTargetSpeed ); + if ( diffSpeed > PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD ) + { + // change to ramp state + dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_RAMP_UP_STATE; + } + } + + dialysatePumps[ pumpId ].prevPumpTargetSpeed = getDialysatePumpTargetSpeed( pumpId ); result = TRUE; } else @@ -244,14 +269,27 @@ * @brief * The signalDialysatePumpHardStop function stops the Dialysate pump immediately. * @details \b Inputs: none - * @details \b Outputs: currentPumpSpeed,pumpTargetSpeed,dialysatePumpState, + * @details \b Outputs: control,currentPumpSpeed,pumpTargetSpeed,dialysatePumpState, * controlTimerCounter,isDialPumpOn. * @param pumpId pump id to stop the given dialysate pump * @return none *************************************************************************/ void signalDialysatePumpHardStop( DIALYSATE_PUMPS_T pumpId ) { - stopDialysatePump( pumpId ); + //Update control to stop the dialysate pump + if ( FRESH_DIALYSATE_PUMP == pumpId ) + { + // dialysate pump control run enable + dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; + setFPGAFreshDialysatePumpControl( dialysatePumps[ pumpId ].control ); + setFPGAFreshDialysatePumpSpeed( DIALYSATE_PUMP_SPEED_ZERO_RPM ); + } + else + { + dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; + setFPGASpentDialysatePumpControl( dialysatePumps[ pumpId ].control ); + setFPGASpentDialysatePumpSpeed( DIALYSATE_PUMP_SPEED_ZERO_RPM ); + } // Reset all the variables to stop mode dialysatePumps[ pumpId ].currentPumpSpeed = 0.0F; @@ -315,14 +353,18 @@ * by FPGA * @details \b Outputs: measuredPumpSpeed,dialysatePumpMeasuredCurrentA, * measuredDirection,directionErrorCount - * @detail \b Alarms: ALARM_ID_DD_XXX_DIALYSATE_PUMP_RPM_OUT_OF_RANGE when - * speed mismatch occurs between set and measured speed. - * @detail \b Alarms: ALARM_ID_DD_XXX_DIALYSATE_PUMP_OFF_FAULT when dialysate - * pump runs at certain speed when not commanded to run. - * @detail \b Alarms: ALARM_ID_DD_XXX_DIALYSATE_PUMP_DIRECTION_INVALID when - * dialysate pump is not running in forward direction. - * @detail \b Alarms:ALARM_ID_DD_XXX_DIALYSATE_PUMP_CURRENT_OUT_OF_RANGE when - * dialysate pump is drawing more current than expected. + * @detail \b Alarms: ALARM_ID_DD_FRESH_DIALYSATE_PUMP_RPM_OUT_OF_RANGE, + * ALARM_ID_DD_SPENT_DIALYSATE_PUMP_RPM_OUT_OF_RANGE when speed mismatch + * occurs between set and measured speed. + * @detail \b Alarms: ALARM_ID_DD_FRESH_DIALYSATE_PUMP_OFF_FAULT, + * ALARM_ID_DD_SPENT_DIALYSATE_PUMP_OFF_FAULT when dialysate pump runs at + * certain speed when not commanded to run. + * @detail \b Alarms: ALARM_ID_DD_FRESH_DIALYSATE_PUMP_DIRECTION_INVALID, + * ALARM_ID_DD_SPENT_DIALYSATE_PUMP_DIRECTION_INVALID when dialysate pump is + * not running in forward direction. + * @detail \b Alarms:ALARM_ID_DD_FRESH_DIALYSATE_PUMP_CURRENT_OUT_OF_RANGE, + * ALARM_ID_DD_SPENT_DIALYSATE_PUMP_CURRENT_OUT_OF_RANGE when dialysate pump + * is drawing more current than expected. * @return none *************************************************************************/ void execDialysatePumpMonitor( void ) @@ -486,7 +528,7 @@ SELF_TEST_STATUS_T execDialysatePumpSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - BOOL calStatus = FALSE; + BOOL calStatus = TRUE; // TODO:initialize to false when calibration records avialble // This is only one record the number of items to check is 0 since the get NV data function does not do a for loop to check the calibration time // calStatus |= getNVRecord2Driver( GET_CAL_FRESH_DIALYSATE_PUMP_RECORD, (U08*)&freshDialysatePumpRecord, sizeof( DD_FRESH_DIALYSATE_PUMP_RECORD_T ), 0, @@ -513,7 +555,7 @@ * @brief * The isDialysatePumpOn function determines whether the dialysate pump is on * or Off state. - * @details \b Inputs: none + * @details \b Inputs: dialysatePumps[] * @details \b Outputs: none * @param pumpId dialysate pump id to return status of dialysate pump running state * @return TRUE if dialysate pump is on, FALSE if not. @@ -537,11 +579,11 @@ DIALYSATE_PUMP_STATE_T result = DIALYSATE_PUMP_OFF_STATE; F32 targetSpeed = getDialysatePumpTargetSpeed( pumpId ); - if ( targetSpeed > NEARLY_ZERO ) + if ( targetSpeed > ZERO_SPEED ) { if ( FRESH_DIALYSATE_PUMP == pumpId ) { - // dialysate pump control run enable + // dialysate pump control run enable, forward run only. dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_RUN; setFPGAFreshDialysatePumpControl( dialysatePumps[ pumpId ].control ); } @@ -606,7 +648,7 @@ BOOL hasTgtBeenReached = FALSE; F32 currentToTargetDiff = fabs( getDialysatePumpTargetSpeed( pumpId ) - dialysatePumps[ pumpId ].currentPumpSpeed ); - if ( currentToTargetDiff > NEARLY_ZERO ) + if ( currentToTargetDiff > ZERO_SPEED ) { if ( currentToTargetDiff > DIALYSATE_PUMP_SPEED_INCREMENT ) { @@ -627,13 +669,13 @@ dialysatePumps[ pumpId ].currentPumpSpeed += speedIncrease; // If the pump's target speed is set to be 0, do not ramp down set it to zero immediately - if ( getDialysatePumpTargetSpeed( pumpId ) < NEARLY_ZERO ) + if ( getDialysatePumpTargetSpeed( pumpId ) < ZERO_SPEED ) { dialysatePumps[ pumpId ].currentPumpSpeed = 0.0F; } } - if ( dialysatePumps[ pumpId ].currentPumpSpeed > NEARLY_ZERO ) + if ( dialysatePumps[ pumpId ].currentPumpSpeed > ZERO_SPEED ) { if ( FRESH_DIALYSATE_PUMP == pumpId ) { @@ -700,41 +742,14 @@ //Set spent dialyate pump speed setFPGASpentDialysatePumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); } - dialysatePumps[ pumpId ].controlTimerCounter = 0; + dialysatePumps[ pumpId ].controlTimerCounter = 0; } return state; } /*********************************************************************//** * @brief - * The stopDialysatePump function sets the given dialysate pump rpm to zero and stops - * the pump. - * @details \b Inputs: dialysatePumps - * @details \b Outputs: dialysatePumps - * @param pumpId dialysate pump id to set the diaylsate pump control - * @return none - *************************************************************************/ -static void stopDialysatePump( DIALYSATE_PUMPS_T pumpId ) -{ - //Update control to stop the dialysate pump - if ( FRESH_DIALYSATE_PUMP == pumpId ) - { - // dialysate pump control run enable - dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; - setFPGAFreshDialysatePumpControl( dialysatePumps[ pumpId ].control ); - setFPGAFreshDialysatePumpSpeed( DIALYSATE_PUMP_SPEED_ZERO_RPM ); - } - else - { - dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; - setFPGASpentDialysatePumpControl( dialysatePumps[ pumpId ].control ); - setFPGASpentDialysatePumpSpeed( DIALYSATE_PUMP_SPEED_ZERO_RPM ); - } -} - -/*********************************************************************//** - * @brief * The getDialysatePumpTargetSpeed function gets the current target speed for the given * dialysate pump. * @details \b Inputs: pumpTargetSpeed 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; -} - /**@}*/ Index: firmware/App/Controllers/Heaters.h =================================================================== diff -u -r3b3833a0b1aed89f1ff66104519f658f5a41fa99 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision 3b3833a0b1aed89f1ff66104519f658f5a41fa99) +++ firmware/App/Controllers/Heaters.h (.../Heaters.h) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -38,6 +38,7 @@ typedef enum Heaters { DD_PRIMARY_HEATER = 0, ///< DD primary heater + DD_HEATERS_FIRST = DD_PRIMARY_HEATER, ///< First heater DD_TRIMMER_HEATER, ///< DD trimmer heater NUM_OF_DD_HEATERS, ///< Number of the heaters } DD_HEATERS_T; @@ -51,10 +52,8 @@ F32 trimmerTargetTemp; ///< Trimmer heater target temperature U32 primaryHeaterState; ///< Primary heater state U32 trimmerHeaterState; ///< Trimmer heater state - F32 primaryCalcTargetTemp; ///< Primary heater calculated target temperature - F32 trimmerCalcCurrentTemp; ///< Trimmer heater calculated current temperature - U32 primaryControlCounter; ///< Primary heater control count - U32 trimmerControlCounter; ///< Trimmer heater control count + U32 primaryControlCounter; ///< Primary heater control interval count + U32 trimmerControlCounter; ///< Trimmer heater control interval count } HEATERS_DATA_T; // ********** Public function prototypes ********** @@ -65,12 +64,11 @@ F32 getHeaterTargetTemperature( DD_HEATERS_T heater ); BOOL isHeaterOn( DD_HEATERS_T heater ); void stopHeater( DD_HEATERS_T heater ); -void execHeaters( void ); +void execHeatersControl( void ); void execHeatersMonitor( void ); BOOL testHeatersDataPublishIntervalOverride( MESSAGE_T *message ); -BOOL testSetHeaterDutyCycleOverride( U32 heater, F32 value ); -BOOL testResetHeaterDutyCycleOverride( U32 heater ); +BOOL testHeaterDutyCycleOverride( MESSAGE_T *message ); /**@}*/ Index: firmware/App/Monitors/Level.c =================================================================== diff -u -ra14bc308c72272ce0275d263cf010c90d8a37355 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Monitors/Level.c (.../Level.c) (revision a14bc308c72272ce0275d263cf010c90d8a37355) +++ firmware/App/Monitors/Level.c (.../Level.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -61,7 +61,7 @@ *************************************************************************/ void initLevels( void ) { - U08 i; + U32 i; levelsDataPublicationCounter = DATA_PUBLISH_COUNTER_START_COUNT; @@ -88,8 +88,8 @@ *************************************************************************/ void execLevels( void ) { - U08 i; - U08 currentLevelStatus = 0; + U32 i; + U32 currentLevelStatus = 0; for ( i = 0; i < NUM_OF_LEVELS; i++ ) { Index: firmware/App/Monitors/Level.h =================================================================== diff -u -ra14bc308c72272ce0275d263cf010c90d8a37355 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Monitors/Level.h (.../Level.h) (revision a14bc308c72272ce0275d263cf010c90d8a37355) +++ firmware/App/Monitors/Level.h (.../Level.h) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -20,7 +20,6 @@ #include "DDCommon.h" - /** * @defgroup Level Level * @brief Level module monitors the floater levels, Bicarb gas separation level and Spent Index: firmware/App/Monitors/Pressure.c =================================================================== diff -u -r48c75a394c56b82886760e9a136b638edecf7572 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Monitors/Pressure.c (.../Pressure.c) (revision 48c75a394c56b82886760e9a136b638edecf7572) +++ firmware/App/Monitors/Pressure.c (.../Pressure.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -476,6 +476,7 @@ if ( ++pressuresDataPublicationTimerCounter >= getU32OverrideValue( &pressuresDataPublishInterval ) ) { PRESSURE_TEMP_DATA_T data; + data.filteredWaterInletInputPressure = getFilteredPressure( PRESSURE_SENSOR_WATER_INLET_INPUT ); data.filteredWaterInletOutputPressure = getFilteredPressure( PRESSURE_SENSOR_WATER_INLET_OUTPUT ); data.filteredHydraulicsOutletPressure = getFilteredPressure( PRESSURE_SENSOR_HYDRAULICS_OUTLET ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -rae0c2f3cbae7797dc48c1d7aa477975395714317 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision ae0c2f3cbae7797dc48c1d7aa477975395714317) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -113,7 +113,8 @@ MSG_ID_DD_DIALYSATE_PUMPS_TARGET_PRESSURE_OVERRIDE_REQUEST, MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_CURRENT_OVERRIDE_REQUEST, MSG_ID_DD_DIALYSATE_PUMPS_MEASURED_DIRECTION_OVERRIDE_REQUEST, //35 - MSG_ID_DD_HEATERS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, // TODO:Heaters duty cycle to be added + MSG_ID_DD_HEATERS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + MSG_ID_DD_HEATERS_DUTY_CYCLE_OVERRIDE_REQUEST, MSG_ID_DD_LEVELS_PUBLISH_INTERVAL_OVERRIDE_REQUEST, MSG_ID_DD_LEVELS_STATUS_OVERRIDE_REQUEST, }; @@ -156,6 +157,7 @@ &testDialysatePumpMeasuredCurrentOverride, &testDialysatePumpMeasuredDirectionOverride, //35 &testHeatersDataPublishIntervalOverride, + &testHeaterDutyCycleOverride, &testLevelsDataPublishIntervalOverride, &testLevelStatusOverride, }; Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -ra14bc308c72272ce0275d263cf010c90d8a37355 -rc85d9f0a8023fabdf1cd557965958d225e2b9085 --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision a14bc308c72272ce0275d263cf010c90d8a37355) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision c85d9f0a8023fabdf1cd557965958d225e2b9085) @@ -91,7 +91,7 @@ //execSwitches(); // Heaters controller - execHeaters(); + execHeatersControl(); // Monitor RAM error status //execRAMMonitor();