Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u -rdedf0cbae7f010d314c430f06834114213e18f2c -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision dedf0cbae7f010d314c430f06834114213e18f2c) +++ firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -35,7 +35,7 @@ #define CONCENTRATE_PUMP_FORWARD_DIR 0x1 ///< Concentrate pump forward direction configuration. #define CONCENTRATE_PUMP_REVERSE_DIR 0x0 ///< Concentrate pump reverse direction configuration. -#define CONCENTRATE_PUMP_SPEED_INCREMENT 10.0F ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. +#define CONCENTRATE_PUMP_RAMP_SPEED_INCREMENT 10.0F ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. #define CONCENTRATE_PUMP_MIN_SPEED 3.0F ///< Minimum speed for concentrate pump in mL per min. #define CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_ON_PCT 0.02F ///< Concentrate pump speed out of range tolerance when on in percentage. #define CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_SLOW_MLPM 1.0F ///< Concentrate pump speed out of range tolerance when slow in mL/min. @@ -54,7 +54,7 @@ #define CONCENTRATE_PUMP_HALL_SENSORS_OUT_OF_RANGE_TIME_MS ( 5 * MS_PER_SECOND ) ///< Hall sensors out of range time in milliseconds. #define CONCENTRATE_PUMP_MICRO_STEPS_PER_STEP 8.0F ///< Number of micro-steps ( fractions of step) per step. -#define CONCENTRATE_PUMP_VOLUME_TO_REVOLUTION ( ( 1 / CONCENTRATE_PUMP_VOLUME_PER_REV ) * \ +#define CONCENTRATE_PUMP_VOLUME_TO_REVOLUTION ( ( 1.0F / CONCENTRATE_PUMP_VOLUME_PER_REV ) * \ ( CONCENTRATE_PUMP_STEP_PER_REV * \ CONCENTRATE_PUMP_MICRO_STEPS_PER_STEP ) ) ///< Convert volume in to number of revolutions needed. #ifdef __PUMPTEST__ @@ -87,7 +87,6 @@ #define CONCENTRATE_PUMP_CONTROL_SLEEP_OFF 0x40 ///< Concentrate pump control sleep off. #define CONCENTRATE_PUMP_CONTROL_ENABLE_MASK 0x10 ///< Concentrate pump control enable bit mask. - static const U32 CONCENTRATE_PUMP_CONTROL_FORWARD = CONCENTRATE_PUMP_CONTROL_SLEEP_OFF | CONCENTRATE_PUMP_CONTROL_NOT_RESET | CONCENTRATE_PUMP_CONTROL_ENABLE | @@ -165,6 +164,7 @@ static void monitorPumpSpeed( CONCENTRATE_PUMPS_T pumpId, ALARM_ID_T alarm ); static void checkConcentratePumpControlSet( CONCENTRATE_PUMPS_T pumpId ); static void publishConcentratePumpData( void ); +static void monitorPumpParkStatus( void ); /*********************************************************************//** * @brief @@ -253,14 +253,39 @@ // Calculate pump speed for each defined pump calcMeasuredPumpsSpeed(); + // Update rev count status + pumpMesauredRevCnt[ D11_PUMP ].data = (U32)getFPGAD11PumpRevolutionCountStatus(); + pumpMesauredRevCnt[ D10_PUMP ].data = (U32)getFPGAD10PumpRevolutionCountStatus(); + + //Monitor Pump Park status + monitorPumpParkStatus(); + + //Monitor Pump Speed + monitorPumpSpeed( D11_PUMP, ALARM_ID_DD_D11_PUMP_SPEED_CONTROL_ERROR ); + monitorPumpSpeed( D10_PUMP, ALARM_ID_DD_D10_PUMP_SPEED_CONTROL_ERROR ); + + checkPersistentAlarm( ALARM_ID_DD_CONCENTRATE_PUMP_FAULT, isConcPumpFault, fpgaConcPumpsFault, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD ); + + //Publish concentrate pump data + publishConcentratePumpData(); +} + +/*********************************************************************//** + * @brief + * The monitorPumpParkStatus function monitors the concentrate pump park status + * and associated fault handling. + * @details \b Inputs: Park status + * @details \b Outputs: isConcPumpParkInProgress,acidConcentratePumpParkPersistenceClear + * bicarbConcentratePumpParkPersistenceClear + * @return none + *************************************************************************/ +static void monitorPumpParkStatus( void ) +{ parked[ D11_PUMP ].data = (U32)getFPGAD11PumpIsParked(); - parked[ D10_PUMP ].data = (U32)getFPGAD10PumpIsParked(); + parked[ D10_PUMP ].data = (U32)getFPGAD10PumpIsParked(); parkFaulted[ D11_PUMP ].data = (U32)getFPGAD11PumpParkFault(); - parkFaulted[ D10_PUMP ].data = (U32)getFPGAD10PumpParkFault(); + parkFaulted[ D10_PUMP ].data = (U32)getFPGAD10PumpParkFault(); - pumpMesauredRevCnt[ D11_PUMP ].data = (U32)getFPGAD11PumpRevolutionCountStatus(); - pumpMesauredRevCnt[ D10_PUMP ].data = (U32)getFPGAD10PumpRevolutionCountStatus(); - if ( ( TRUE == getConcPumpIsParked( D11_PUMP ) ) || ( TRUE == getConcPumpParkIsFaulted( D11_PUMP ) ) ) { // If the pump has parked or faulted during the park, then it is not in progress @@ -297,14 +322,6 @@ resetPersistentAlarmTimer( ALARM_ID_DD_D10_PUMP_SPEED_CONTROL_ERROR ); } } - - monitorPumpSpeed( D11_PUMP, ALARM_ID_DD_D11_PUMP_SPEED_CONTROL_ERROR ); - monitorPumpSpeed( D10_PUMP, ALARM_ID_DD_D10_PUMP_SPEED_CONTROL_ERROR ); - - checkPersistentAlarm( ALARM_ID_DD_CONCENTRATE_PUMP_FAULT, isConcPumpFault, fpgaConcPumpsFault, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD ); - - //Publish concentrate pump data - publishConcentratePumpData(); } /*********************************************************************//** @@ -335,13 +352,11 @@ concentratePumps[ pumpId ].execState = handleConcentratePumpControlTargetSpeedState( pumpId ); break; -#ifndef _VECTORCAST_ // The switch case is in a for loop so the default case cannot be covered in VectorCAST default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_EXEC_INVALID_STATE, pumpId ) concentratePumps[ pumpId ].execState = CONCENTRATE_PUMP_OFF_STATE; break; -#endif } } } @@ -485,6 +500,7 @@ * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. * @param pumpId pump id to set step speed * @param targetSpeed_ml_min target speed in mL/min + * @param targetVolume_ml dosing volume to be delivered in ml. * @return none *************************************************************************/ void setConcentratePumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId, F32 targetSpeed_ml_min, F32 targetVolume_ml ) @@ -573,6 +589,28 @@ /*********************************************************************//** * @brief + * The isConcentratePumpDosingCompleted function returns the dosing status + * for a given concentrate pump. + * @details \b Inputs: concentratePumps + * @details \b Outputs: none + * @param pumpId concentrate pump id to get current dosing status + * @return TRUE if dosing completed otherwise,FALSE. + *************************************************************************/ +BOOL isConcentratePumpDosingCompleted( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL state = FALSE; + + //On dosing completion,state transition to off state + if ( CONCENTRATE_PUMP_OFF_STATE == concentratePumps[ pumpId ].execState ) + { + state = TRUE; + } + + return state; +} + +/*********************************************************************//** + * @brief * The getPumpTargetSpeed function gets the current target spped for the given * concentrate pump. * @details \b Inputs: pumpTargetSpeed @@ -682,28 +720,6 @@ /*********************************************************************//** * @brief - * The IsConcentratePumpDosingCompleted function gets the concentrate pump - * dosing completion status. - * @details \b Inputs: execState - * @details \b Outputs: none - * @return true when dosing completed,otherwise false. - *************************************************************************/ -BOOL IsConcentratePumpDosingCompleted( void ) -{ - BOOL result = FALSE; - - // Check doisng completed status - if ( ( concentratePumps[D11_PUMP].execState == CONCENTRATE_PUMP_OFF_STATE ) && - ( concentratePumps[D10_PUMP].execState == CONCENTRATE_PUMP_OFF_STATE ) ) - { - result = TRUE; - } - - return result; -} - -/*********************************************************************//** - * @brief * The getConcPumpCurrentMeasuredRevolutionCount function gets the concentrate pump * current measured revolution count. * @details \b Inputs: pumpMesauredRevCnt @@ -804,14 +820,10 @@ if ( D11_PUMP == pumpId ) { setFPGAD11PumpSetStepSpeed( CONCENTRATE_PUMP_ZERO_FLOW_RATE ); - //concentratePumps[ D11_PUMP ].controlSet |= CONCENTRATE_PUMP_CONTROL_ENABLE_MASK; - //setFPGAD11PumpControl( concentratePumps[ D11_PUMP ].controlSet ); } else { setFPGAD10PumpSetStepSpeed( CONCENTRATE_PUMP_ZERO_FLOW_RATE ); - //concentratePumps[ D10_PUMP ].controlSet |= CONCENTRATE_PUMP_CONTROL_ENABLE_MASK; - //setFPGAD10PumpControl( concentratePumps[ D10_PUMP ].controlSet ); } #ifndef __PUMPTEST__ // Park concentrate pump too if requested @@ -960,9 +972,9 @@ if ( currentToTargetDiff > NEARLY_ZERO ) { - if ( currentToTargetDiff > CONCENTRATE_PUMP_SPEED_INCREMENT ) + if ( currentToTargetDiff > CONCENTRATE_PUMP_RAMP_SPEED_INCREMENT ) { - speedIncrease = CONCENTRATE_PUMP_SPEED_INCREMENT; + speedIncrease = CONCENTRATE_PUMP_RAMP_SPEED_INCREMENT; } else { @@ -1035,24 +1047,15 @@ for ( pumpId = CONCENTRATEPUMPS_FIRST; pumpId < NUM_OF_CONCENTRATE_PUMPS; pumpId++ ) { - switch ( pumpId ) + if ( D11_PUMP == pumpId ) { - case D11_PUMP: - pulseWidthCount = getFPGAD11PumpHallSensePulseWidth(); - break; + pulseWidthCount = getFPGAD11PumpHallSensePulseWidth(); + } + else + { + pulseWidthCount = getFPGAD10PumpHallSensePulseWidth(); + } - case D10_PUMP: - pulseWidthCount = getFPGAD10PumpHallSensePulseWidth(); - break; - -#ifndef _VECTORCAST_ - // Disabled in VectorCAST since it cannot be reached in VectorCAST because the switch case is in a for loop - default: - // Loop only allows for valid concentrate pump Ids. - break; -#endif - } - pulseWidthInMicroSeconds = pulseWidthCount * CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION; concentratePumps[ pumpId ].pulseWidthUS = pulseWidthInMicroSeconds; isPumpPulseWidthOut = ( pulseWidthInMicroSeconds <= (F32)CONCENTRATE_PUMP_MIN_ALLOWED_HALL_SENSOR_COUNT ? TRUE : FALSE ); @@ -1121,37 +1124,30 @@ * required set bit, they are set again. * @details \b Inputs: concentratePumps * @details \b Outputs: none - * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. * @param pumpId pump id to check its control set bit * @return none *************************************************************************/ static void checkConcentratePumpControlSet( CONCENTRATE_PUMPS_T pumpId ) { U08 controlSetBits; - switch ( pumpId ) + if ( D11_PUMP == pumpId ) { - case D11_PUMP: - controlSetBits = getFPGAD11PumpControlStatus(); + controlSetBits = getFPGAD11PumpControlStatus(); - if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) - { - setFPGAD11PumpControl( concentratePumps[ pumpId ].controlSet ); - } - break; + if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) + { + setFPGAD11PumpControl( concentratePumps[ pumpId ].controlSet ); + } + } + else + { + controlSetBits = getFPGAD10PumpControlStatus(); - case D10_PUMP: - controlSetBits = getFPGAD10PumpControlStatus(); - - if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) - { - setFPGAD10PumpControl( concentratePumps[ pumpId ].controlSet ); - } - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); - break; + if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) + { + setFPGAD10PumpControl( concentratePumps[ pumpId ].controlSet ); + } } } @@ -1325,7 +1321,7 @@ { BOOL result = FALSE; - // Verify tester has logged in with TD + // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid Index: firmware/App/Controllers/DialysatePumps.c =================================================================== diff -u -rab7c459d5cd92f74babd8ca1ce8aa47354570728 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision ab7c459d5cd92f74babd8ca1ce8aa47354570728) +++ firmware/App/Controllers/DialysatePumps.c (.../DialysatePumps.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -17,6 +17,7 @@ #include +#include "BalancingChamber.h" #include "DialysatePumps.h" #include "FpgaDD.h" #include "MessageSupport.h" @@ -38,16 +39,14 @@ */ // ********** private definitions ********** -//TODO : Testing - changing control interval -//#define DIALYSATE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump data is published on the CAN bus. -#define DIALYSATE_PUMP_DATA_PUB_INTERVAL ( 50 / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump data is published on the CAN bus. +#define DIALYSATE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump data is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. -#define DP_CONTROL_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. -//#define DP_CONTROL_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. +#define DP_CONTROL_INTERVAL_MS 1000 ///< Dialysate pump control interval in ms +#define DP_CONTROL_INTERVAL ( DP_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the dialysate pump is controlled. #define DIALYSATE_PUMP_CONTROL_RUN 0x01 ///< Dialysate pump control run pump. #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 10.0F ///< Speed increase when controlling dialysate pump to target step speed. +#define DIALYSATE_PUMP_RAMP_SPEED_INCREMENT 10.0F ///< Speed increase when controlling dialysate pump ramp 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. @@ -61,25 +60,21 @@ #define MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< FPGA dialysate pump direction fault window #define MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_FAILURES 10 ///< FPGA dialysate pump direction fault failures per MAX_FPGA_DIALYSATE_PUMP_DIRECTION_FAULT_WINDOW_MS -//#define FRESH_DIALYSATE_TARGET_PRESSURE_PSI (-12.0F) ///< Fresh dialysate pump recommended pressure(Pn/PHo) in psi. -//#define FRESH_DIALYSATE_MAX_PRESSURE_PSI (-15.0F) ///< Fresh dialysate pump maximum allowed (Pn/PHo) pressure in psi. #define FRESH_DIALYSATE_TARGET_PRESSURE_PSI 25.0F ///< Fresh dialysate pump recommended pressure(D18) in psi. #define FRESH_DIALYSATE_MAX_PRESSURE_PSI 26.0F ///< Fresh dialysate pump maximum allowed (D18) pressure in psi. #define SPENT_DIALYSATE_TARGET_PRESSURE_PSI 29.0F ///< Spent dialysate pump recommended pressure(PDs) in psi. #define SPENT_DIALYSATE_MAX_PRESSURE_PSI 30.0F ///< Spent dialysate pump maximum allowed (PDs) pressure in psi. -#define DIALYSATE_PUMP_MIN_PRESSURE_PSI 4.0F ///< Minimum dialysate pump pressure in psi. -#define FRESH_DIAL_OPEN_LOOP_SPEED_RPM 2000.0F ///< fresh dialysate pump open loop speed to meet target speed. -#define SPENT_DIAL_OPEN_LOOP_SPEED_RPM 2500.0F ///< spent dialysate pump open loop speed to meet target speed. +#define FRESH_DIAL_OPEN_LOOP_SPEED_RPM 2000.0F ///< fresh dialysate pump open loop speed to meet target pressure. +#define SPENT_DIAL_OPEN_LOOP_SPEED_RPM 2500.0F ///< spent dialysate pump open loop speed to meet target pressure. #define DIALYSATE_PUMP_SPEED_ZERO_RPM 0 ///< Dialysate pump zero RPM speed. #define SPEED_COUNT_ZERO 0 ///< Measured speed count zero check. #define SPEED_CONV_FACTOR 1500000 ///< Measured speed count conversion to RPM -#define D12_PRES_TO_SPD_CONV_FACTOR 106.0F ///< Pressure to speed conversion factor for fresh dialysate pump control. -#define D48_PRES_TO_SPD_CONV_FACTOR 91.4F ///< Pressure to speed conversion factor for fresh dialysate pump control. #define D12_PUMP_P_COEFFICIENT 20.0F ///< P term for fresh dialysate pump delta pressure control. #define D12_PUMP_I_COEFFICIENT 60.0F ///< I term for fresh dialysate pump delta pressure control. #define D48_PUMP_P_COEFFICIENT 20.0F ///< P term for spent dialysate pump delta pressure control. #define D48_PUMP_I_COEFFICIENT 60.0F ///< I term for spent dialysate pump delta pressure control. +#define DIAL_PUMP_NO_FEED_FORWARD 0.0F ///< Feedforward term for dialysate pump 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. @@ -123,6 +118,7 @@ U32 pumpID; ///< Pump ID Fresh(DGP) : 0, Spent ( SDP) : 1 U32 startStop; ///< Stop : 0, Start : 1 U32 rpm; ///< Speed range from 300 to 4500 RPM range + U32 pumpControl; ///< 1 : Open Loop control, 0 : Closed loop control } DIAL_PUMP_START_STOP_CMD_PAYLOAD_T; // ********** private data ********** @@ -138,12 +134,14 @@ static OVERRIDE_F32_T dialysatePumpMeasuredCurrentA[ NUM_OF_DIALYSATE_PUMPS ]; ///< Measured dialysate pump current feedback. static OVERRIDE_U32_T measuredDirection[ NUM_OF_DIALYSATE_PUMPS ]; ///< Measured dialysate pump direction. static OVERRIDE_F32_T pumpTargetPressure[ NUM_OF_DIALYSATE_PUMPS ]; ///< Target dialysate pumps' pressure (PSI). +static BOOL isDialPumpOpenLoopEnabled[ NUM_OF_DIALYSATE_PUMPS ]; ///< Flag to run in open loop control mode. +static BOOL dialPumpsReadyToControl; ///< Flag use to indicate the minimum control interval is met for pump control + //For testing #ifdef __PITEST__ static F32 pIControlSignal[ NUM_OF_CONTROLLER_SIGNAL ]; #endif -//TODO : Validate once HDD defines the conversion. static const F32 CURRENT_CONVERSION_COEFF = (F32)( 2.5F / ( BITS_12_FULL_SCALE - 1.0F ) ); // ********** private function prototypes ********** @@ -159,15 +157,17 @@ * @brief * The initDialysatePump function initializes the DialysatePumps unit. * @details \b Inputs: none - * @details \b Outputs: Dialysate unit variables initialized. + * @details \b Outputs: Dialysate pump unit variables initialized. * @return none *************************************************************************/ void initDialysatePump( void ) { DIALYSATE_PUMPS_T pumpId; + #ifdef __PITEST__ U32 i; #endif + dialysatePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; for ( pumpId = DIALYSATE_PUMPS_FIRST; pumpId < NUM_OF_DIALYSATE_PUMPS; pumpId++ ) @@ -196,6 +196,8 @@ dialysatePumps[ pumpId ].control = DIALYSATE_PUMP_CONTROL_STOP; dialysatePumps[ pumpId ].directionErrorCount = 0; dialysatePumps[ pumpId ].lastDirectionErrorCount = 0; + isDialPumpOpenLoopEnabled[ pumpId ] = FALSE; + dialPumpsReadyToControl = FALSE; signalDialysatePumpHardStop( pumpId ); } @@ -211,11 +213,11 @@ // Initialize the fresh dialysate pump PI controller initializePIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, D12_PUMP_P_COEFFICIENT, D12_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM ); + MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM, FALSE, DIAL_PUMP_NO_FEED_FORWARD ); // Initialize spent dialysate pump PI controller initializePIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, D48_PUMP_P_COEFFICIENT, D48_PUMP_I_COEFFICIENT, - MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM ); + MIN_DIALYSATE_PUMP_RPM, MAX_DIALYSATE_PUMP_RPM,FALSE, DIAL_PUMP_NO_FEED_FORWARD ); // Init the dialysate pump with valid PWM while motor is disabled. // when enable triggers, we dont want invlid RPM set that triggers alarm in motor controller. @@ -228,6 +230,18 @@ pIControlSignal[ i ] = 0.0F; } #endif + + // Init the dialysate pump with valid PWM while motor is disabled. + // when enable triggers, we dont want invlid RPM set that triggers alarm in motor controller. + setFPGAD12PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); + setFPGAD48PumpSpeed( MIN_DIALYSATE_PUMP_RPM ); + +#ifdef __PITEST__ + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = 0.0F; + } +#endif // Initialize the persistent alarms for fresh dialysate pump initPersistentAlarm( ALARM_ID_DD_D12_PUMP_RPM_OUT_OF_RANGE, RPM_OUT_OF_RANGE_TIME_OUT, RPM_OUT_OF_RANGE_TIME_OUT ); initPersistentAlarm( ALARM_ID_DD_D12_PUMP_OFF_FAULT, SAFETY_SHUTDOWN_TIMEOUT, SAFETY_SHUTDOWN_TIMEOUT ); @@ -254,9 +268,10 @@ * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump id supplied. * @param pumpId pump id to set the new speed. * @param rpm new dialysate pump target RPM + * @param isOpenLoopControlEnabled dialysate pump control method * @return TRUE if new target RPM is set, FALSE if not *************************************************************************/ -BOOL setDialysatePumpTargetRPM( DIALYSATE_PUMPS_T pumpId, U32 rpm ) +BOOL setDialysatePumpTargetRPM( DIALYSATE_PUMPS_T pumpId, U32 rpm, BOOL isOpenLoopControlEnabled ) { BOOL result = FALSE; @@ -268,13 +283,17 @@ } else if ( rpm < MIN_DIALYSATE_PUMP_RPM ) { - pumpTargetSpeed[ pumpId ].data = 0.0; + // Lets assign minimum speed to make sure, driver is not getting into fault mode + pumpTargetSpeed[ pumpId ].data = MIN_DIALYSATE_PUMP_RPM; } else { pumpTargetSpeed[ pumpId ].data = MAX_DIALYSATE_PUMP_RPM; } + // Open loop or close loop control + isDialPumpOpenLoopEnabled[ pumpId ] = isOpenLoopControlEnabled; + //handle target speed update when pump is running if ( DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE == dialysatePumps[ pumpId ].dialysatePumpState ) { @@ -329,15 +348,16 @@ dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; dialysatePumps[ pumpId ].controlTimerCounter = 0; dialysatePumps[ pumpId ].isDialPumpOn = FALSE; + isDialPumpOpenLoopEnabled[ pumpId ] = FALSE; //Reset PI Controller if ( D12_PUMP == pumpId ) { - resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } else { - resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } } @@ -437,7 +457,7 @@ isOffCurrentOut = ( getDialysatePumpMeasuredCurrentA( pumpId ) > DIALYSATE_PUMP_MAX_CURRENT_WHEN_OFF_A ? TRUE : FALSE ); isRPMTooHigh = ( getDialysatePumpMeasuredSpeed( pumpId ) > MIN_DIALYSATE_PUMP_RPM ? TRUE : FALSE ); - + //TODO : Enable the code later for alarm testing #if 0 if ( D12_PUMP == pumpId ) { @@ -472,6 +492,7 @@ BOOL isDirInvalid = ( ( direction != DIALYSATE_PUMP_FORWARD_DIR ) && ( rpm > DIALYSATE_PUMP_MIN_RPM_FOR_DIR_CHECK ) ? TRUE : FALSE ); isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_RPM_OUT_OF_RANGE ? TRUE : FALSE ); + //TODO : Enable the code later for alarm testing #if 0 if ( D12_PUMP == pumpId ) { @@ -500,6 +521,7 @@ // Check the persistent alarm for the maximum dialysate pump current F32 currentA = getDialysatePumpMeasuredCurrentA( pumpId ); isCurrentOutOfRange = ( currentA > DIALYSATE_PUMP_MAX_CURRENT_A ? TRUE : FALSE ) | isOffCurrentOut; + //TODO : Enable the code later for alarm testing #if 0 if ( D12_PUMP == pumpId ) { @@ -553,13 +575,10 @@ dialysatePumps[ pumpId ].dialysatePumpState = handleDialysatePumpControlToTargetState( pumpId ); break; -#ifndef _VECTORCAST_ - // The switch case is in a for loop so the default case cannot be covered in VectorCAST default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSATE_PUMP_EXEC_INVALID_STATE, pumpId ) dialysatePumps[ pumpId ].dialysatePumpState = DIALYSATE_PUMP_OFF_STATE; break; -#endif } } } @@ -667,11 +686,11 @@ { if ( D12_PUMP == pumpId ) { - resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D12_PUMP, FRESH_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } else { - resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM ); + resetPIController( PI_CONTROLLER_ID_D48_PUMP, SPENT_DIAL_OPEN_LOOP_SPEED_RPM, DIAL_PUMP_NO_FEED_FORWARD ); } state = DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE; } @@ -696,9 +715,9 @@ if ( currentToTargetDiff > ZERO_SPEED ) { - if ( currentToTargetDiff > DIALYSATE_PUMP_SPEED_INCREMENT ) + if ( currentToTargetDiff > DIALYSATE_PUMP_RAMP_SPEED_INCREMENT ) { - speedIncrease = DIALYSATE_PUMP_SPEED_INCREMENT; + speedIncrease = DIALYSATE_PUMP_RAMP_SPEED_INCREMENT; } else { @@ -750,71 +769,56 @@ { DIALYSATE_PUMP_STATE_T state = DIALYSATE_PUMP_CONTROL_TO_TARGET_STATE; - // control at set interval - if ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) + // control at set minimum interval or interval is expired and balance chamber fill is complete + if ( ( ( ++dialysatePumps[ pumpId ].controlTimerCounter >= DP_CONTROL_INTERVAL ) || + ( TRUE == dialPumpsReadyToControl ) ) && ( TRUE != isDialPumpOpenLoopEnabled[ pumpId ] ) ) { - // Control based on the measured and target pressure - if ( D12_PUMP == pumpId ) + dialysatePumps[ pumpId ].controlTimerCounter = 0; + dialPumpsReadyToControl = TRUE; + + // Control happen only when balancing chamber fill is complete. + if ( FALSE == getBalancingChamberFillinProgressStatus() ) { - F32 measuredPressure = getFilteredPressure( D18_PRES ); - F32 targetPressure = getDialysatePumpTargetPressure( pumpId ); + dialPumpsReadyToControl = FALSE; - F32 control = runPIController( PI_CONTROLLER_ID_D12_PUMP, targetPressure, measuredPressure ); + // Control based on the measured and target pressure + if ( D12_PUMP == pumpId ) + { + F32 measuredPressure = getFilteredPressure( D18_PRES ); + F32 targetPressure = getDialysatePumpTargetPressure( pumpId ); + + F32 control = runPIController( PI_CONTROLLER_ID_D12_PUMP, targetPressure, measuredPressure ); #ifdef __PITEST__ - U32 i; + U32 i; - for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) - { - pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D12_PUMP, (PI_CONTROLLER_SIGNALS_ID)i ); - } + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D12_PUMP, (PI_CONTROLLER_SIGNALS_ID)i ); + } #endif - -#if 0 - if ( measuredPressure < targetPressure ) - { - newSpeed = dialysatePumps[ pumpId ].currentPumpSpeed + DIALYSATE_PUMP_SPEED_INCREMENT; + dialysatePumps[ pumpId ].currentPumpSpeed = control; + //Set fresh dialyate pump speed + setFPGAD12PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); } else { - newSpeed = dialysatePumps[ pumpId ].currentPumpSpeed - DIALYSATE_PUMP_SPEED_INCREMENT; - } -#endif - dialysatePumps[ pumpId ].currentPumpSpeed = control; - //Set fresh dialyate pump speed - setFPGAD12PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); + F32 measuredPressure = getFilteredPressure( D51_PRES ); + F32 targetPressure = getDialysatePumpTargetPressure( pumpId ); - } - else - { - F32 measuredPressure = getFilteredPressure( D51_PRES ); - F32 targetPressure = getDialysatePumpTargetPressure( pumpId ); - - F32 control = runPIController( PI_CONTROLLER_ID_D48_PUMP, targetPressure, measuredPressure ); - + F32 control = runPIController( PI_CONTROLLER_ID_D48_PUMP, targetPressure, measuredPressure ); #ifdef __PITEST__ - U32 i; + U32 i; - for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) - { - pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D48_PUMP, (PI_CONTROLLER_SIGNALS_ID)i ); - } + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D48_PUMP, (PI_CONTROLLER_SIGNALS_ID)i ); + } #endif -#if 0 - if ( measuredPressure < targetPressure ) - { - newSpeed = dialysatePumps[ pumpId ].currentPumpSpeed + DIALYSATE_PUMP_SPEED_INCREMENT; + dialysatePumps[ pumpId ].currentPumpSpeed = control; + //Set spent dialyate pump speed + setFPGAD48PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); } - else - { - newSpeed = dialysatePumps[ pumpId ].currentPumpSpeed - DIALYSATE_PUMP_SPEED_INCREMENT; - } -#endif - dialysatePumps[ pumpId ].currentPumpSpeed = control; - //Set spent dialyate pump speed - setFPGAD48PumpSpeed( (U16)dialysatePumps[ pumpId ].currentPumpSpeed ); - } - dialysatePumps[ pumpId ].controlTimerCounter = 0; } return state; @@ -973,7 +977,6 @@ dialPump.d12PumpTargetRPM = pIControlSignal[ 0 ]; dialPump.d48PumpTargetRPM = pIControlSignal[ 1 ]; #endif - dialPump.d12PumpMeasuredSpeed = getDialysatePumpMeasuredSpeed( D12_PUMP ); dialPump.d48PumpMeasuredSpeed = getDialysatePumpMeasuredSpeed( D48_PUMP ); dialPump.d12PumpCurrentSpeed = dialysatePumps[ D12_PUMP ].currentPumpSpeed; @@ -1130,7 +1133,7 @@ { BOOL result = FALSE; - // Verify tester has logged in with TD + // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid @@ -1146,7 +1149,7 @@ if ( ( TRUE == payload.startStop ) && ( ( payload.rpm >= MIN_DIALYSATE_PUMP_RPM ) && ( payload.rpm <= MAX_DIALYSATE_PUMP_RPM ) ) ) { - setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm ); + setDialysatePumpTargetRPM( (DIALYSATE_PUMPS_T)payload.pumpID, payload.rpm, (BOOL)payload.pumpControl ); result = TRUE; } Index: firmware/App/Controllers/Heaters.c =================================================================== diff -u -r3b6bf2cb6d15da8cb273cff109d2c4b1ee99d546 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 3b6bf2cb6d15da8cb273cff109d2c4b1ee99d546) +++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -29,6 +29,7 @@ #include "SafetyShutdown.h" #include "TaskGeneral.h" #include "TaskPriority.h" +#include "TDInterface.h" #include "TemperatureSensors.h" #include "Timers.h" #include "Utilities.h" @@ -40,24 +41,26 @@ // ********** private definitions ********** -#define HEATERS_MAX_DUTY_CYCLE 1.00F ///< Heaters max duty cycle (100%) or ON state -#define HEATERS_MIN_DUTY_CYCLE 0.00F ///< Heaters minimum duty cycle (0.00%) or OFF state -#define D5_HEAT_ON 1.00F ///< Primary heater ON control -#define HEATERS_DISINFECT_DUTY_CYCLE 0.80F ///< Heaters disinfect cycle. -#define HEATERS_DISINFECT_TRANSFER_DUTY_CYCLE 0.60F ///< Heaters disinfect transfer duty cycle. +#define AC_HEATER_TX_MAX_DUTY_CYCLE 0.50F ///< AC Heater Treatement mode max duty cycle (50% of 1400W : 700W ) or ON state +#define AC_HEATER_HEAT_MAX_DUTY_CYCLE 0.70F ///< AC Heater heat disinfect mode max duty cycle (70% of 1400W : 980W ) or ON state +#define AC_HEATER_MAX_DUTY_CYCLE 1.0F ///< AC Heater max duty cycle (100.0%) or ON state +#define DC_HEATER_MAX_DUTY_CYCLE 1.0F ///< DC Heater max duty cycle (100%) or ON state +#define HEATERS_MIN_DUTY_CYCLE 0.0F ///< Heaters minimum duty cycle (0.00%) or OFF state #define HEATERS_DISINFECT_TEMPERATURE_DRIFT_C 3.0F ///< Heaters disinfect temperature drift in C. #define HEATERS_ZERO_DELTA_TEMP_C 0.0F ///< Heaters zero delta temperature in C. #define HEATERS_DUTY_CYCLE_CONVERSION_FACTOR 100.0F ///< Heaters duty cycle 0: OFF, 100: 100% duty cycle. -#define D45_HEAT_GAIN 10.0F ///< Trimmer heater gain for testing. +#define HEATERS_ZERO_EFFICIENCY 0.0F ///< Zero heater efficiency -#define D5_HEAT_P_COEFFICIENT 1.0F ///< P Term for primary heater control. -#define D5_HEAT_I_COEFFICIENT 1.0F ///< I Term for primary heater control. -#define D45_HEAT_P_COEFFICIENT 1.0F ///< P Term for trimmer heater control. -#define D45_HEAT_I_COEFFICIENT 1.0F ///< I Term for trimmer heater control. +#define D5_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control +#define D5_HEAT_TX_P_COEFFICIENT 0.015F ///< P Term for AC primary heater control during treatment mode. +#define D5_HEAT_TX_I_COEFFICIENT 0.0021F ///< I Term for AC primary heater control during treatment mode. -#define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. +#define D45_HEAT_P_COEFFICIENT 0.35F ///< P Term for trimmer heater control. +#define D45_HEAT_I_COEFFICIENT 0.05F ///< I Term for trimmer heater control. +#define D45_HEAT_TX_INIT_FEED_FORWARD 0.0F ///< Initial Feed forward term for heater control -#define HEATER_TEMP_CONTROL_TOLERANCE 2.0F ///< Primary Heater temp tolerance for ON/Off control +#define HEATERS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Heaters data publish interval. +#define HEATER_TEMP_CONTROL_TRANSFER 1.0F ///< Primary Heater temperature difference to switch to control function #define HEATER_TARGET_TEMPERATURE_MIN 10.0F ///< Minimum allowed target temperature for the heaters. #define HEATER_TARGET_TEMPERATURE_MAX 90.0F ///< Maximum allowed target temperature for the heaters. @@ -66,10 +69,22 @@ #define HEATERS_MAX_OPERATING_VOLTAGE_V 24.0F ///< Heaters max operating voltage in volts. #define HEATERS_VOLTAGE_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Heaters voltage out of range time out in milliseconds. #define HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL 0.2F ///< Heaters max voltage out of range tolerance. -#define D45_HEAT_INITIAL_CONTROL_INTERVAL_COUNT ( ( 5 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Trimmer heater initial control interval count. -#define D45_HEAT_CONTROL_INTERVAL_COUNT ( ( 10 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Trimmer heater control interval count. -#define D5_HEAT_CONTROL_INTERVAL_COUNT ( ( 1 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Primary heater control interval count. +#define D5_HEAT_CONTROL_INTERVAL_MS 30000 /// Primary heater control interval in milli seconds +#define D5_HEAT_CONTROL_INTERVAL_COUNT ( D5_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Primary heater control interval count. +#define D45_HEAT_CONTROL_INTERVAL_MS ( 1 * MS_PER_SECOND ) ///< Trimmer heater control interval in milli seconds +#define D45_HEAT_CONTROL_INTERVAL_COUNT ( D45_HEAT_CONTROL_INTERVAL_MS / TASK_GENERAL_INTERVAL ) ///< Trimmer heater control interval count. +#define PRIMARY_HEATER_MAX_PWR_WATTS 1400.0F ///< AC Primary Heater Max Power consumeption in Watts +#define TX_PRIMARY_HEATER_MAX_PWR_WATTS 700.0F ///< Estimated power to be supplied to the primary heater during treatement mode +#define HEAT_PRIMARY_HEATER_MAX_PWR_WATTS 980.0F ///< Estimated power to be supplied to the primary heater during heat disinfect mode +#define MAX_INLET_FLOW_LPM ( 600.0F / 1000.0F ) ///< Maximum inlet flow to hydraulics chamber from FP +#define LITER_IN_ML 1000.0F ///< Liter in milliliter units +#define TRIMMER_HEATER_MAX_PWR_WATTS 120.0F ///< Maximum power supplied to trimmer heater +#define AC_HEATER_PWM_PERIOD 10000 ///< PWM period 100 ms( in 10us resoultion), 1/10Hz = 1000000us/10us = 10000. +#define AC_HEATER_EFFICIENCY 0.90F ///< Approximated AC heater efficiency to be used in energy calcualtions. +#define DC_HEATER_EFFICIENCY 1.0F ///< DC heater efficiency +#define D5_HEAT_CONTROL_INTERVAL_START_COUNT ( D5_HEAT_CONTROL_INTERVAL_COUNT - 10 ) ///< AC heater control interval start count to jump feedforward control from open loop. + #define DATA_PUBLISH_COUNTER_START_COUNT 70 ///< Data publish counter start count. //static const F32 HEATERS_VOLTAGE_TOLERANCE_V = HEATERS_MAX_OPERATING_VOLTAGE_V * HEATERS_MAX_VOLTAGE_OUT_OF_RANGE_TOL; ///< Heaters voltage tolerance in volts. @@ -99,15 +114,25 @@ static HEATER_STATUS_T heatersStatus[ NUM_OF_DD_HEATERS ]; ///< Heaters status. static OVERRIDE_F32_T targetTempC[ NUM_OF_DD_HEATERS ]; ///< Heater target temperature. static OVERRIDE_F32_T control[ NUM_OF_DD_HEATERS ]; ///< Heater control ( Primary : On/Off, Trimmer : Dutycycle). +static OVERRIDE_F32_T pwmPeriod[ NUM_OF_DD_HEATERS ]; ///< Total PWM period ( ON state + Off State of PWM) +static U32 controlInterval[ NUM_OF_DD_HEATERS ]; ///< Heater control interval time. static U32 dataPublicationTimerCounter; ///< Data publication timer counter. +static const F32 WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES = 4184.0F / (F32)SEC_PER_MIN; ///< Water specific heat in J/KgC / 60. static OVERRIDE_U32_T heatersDataPublishInterval = { HEATERS_DATA_PUBLISH_INTERVAL, HEATERS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Heaters data publish time interval. +static F32 convertDC; ///< AC Heater converted duty cycle +static BOOL startupHeaterControl; ///< First time control with the energy equation. +//For testing +#ifdef __HEATERS_DEBUG__ +static F32 pIControlSignal[ NUM_OF_CONTROLLER_SIGNAL ]; +#endif // ********** private function prototypes ********** static HEATERS_STATE_T handleHeaterStateOff( DD_HEATERS_T heater ); 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 F32 calculateDutyCycle( F32 flowrate, F32 deltaTemp, F32 power, F32 efficiency, F32 min, F32 max ); static void setHeaterControl( DD_HEATERS_T heater ); static F32 getHeaterControl( DD_HEATERS_T heater ); @@ -125,8 +150,38 @@ void initHeaters( void ) { DD_HEATERS_T heater; - dataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; +#ifdef __HEATERS_DEBUG__ + U32 i; +#endif + // Assign start count + dataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + + //Enable PWM based heater control + setFPGAD5HeaterPWMEnableControl( TRUE ); + + // Define PWM period for AC heater + pwmPeriod[ D5_HEAT ].data = AC_HEATER_PWM_PERIOD; + pwmPeriod[ D5_HEAT ].ovData = AC_HEATER_PWM_PERIOD; + pwmPeriod[ D5_HEAT ].ovInitData = AC_HEATER_PWM_PERIOD; + pwmPeriod[ D5_HEAT ].override = OVERRIDE_RESET; + + // TODO : Trimmer heater PWM period + pwmPeriod[ D45_HEAT ].data = 0.0F; + pwmPeriod[ D45_HEAT ].ovData = 0.0F; + pwmPeriod[ D45_HEAT ].ovInitData = 0.0F; + pwmPeriod[ D45_HEAT ].override = OVERRIDE_RESET; + + //Initialize Converted Duty cycle + convertDC = 0.0F; + controlInterval[ D5_HEAT ] = D5_HEAT_CONTROL_INTERVAL_COUNT; + controlInterval[ D45_HEAT ] = D45_HEAT_CONTROL_INTERVAL_COUNT; + + // Assign counter close to the target period + heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; + heatersStatus[ D45_HEAT ].controlIntervalCounter = 0; + startupHeaterControl = TRUE; + for ( heater = DD_HEATERS_FIRST; heater < NUM_OF_DD_HEATERS; heater++ ) { targetTempC[ heater ].data = 0.0F; @@ -143,20 +198,26 @@ heatersStatus[ heater ].targetFlowLPM = 0.0F; heatersStatus[ heater ].nomTargetFlowLPM = 0.0F; heatersStatus[ heater ].hasTargetTempChanged = FALSE; - heatersStatus[ heater ].controlIntervalCounter = 0; heatersStatus[ heater ].isThisFirstControl = TRUE; heatersStatus[ heater ].prevDiaTargetFlowLPM = 0.0F; setHeaterControl( heater ); } - // Initialize the primary controller PI controller - initializePIController( PI_CONTROLLER_ID_D5_HEAT, HEATERS_MIN_DUTY_CYCLE, D5_HEAT_P_COEFFICIENT, D5_HEAT_I_COEFFICIENT, - HEATERS_MIN_DUTY_CYCLE, HEATERS_MAX_DUTY_CYCLE ); + // Initialize the primary heater PI controller + initializePIController( PI_CONTROLLER_ID_D5_HEAT, HEATERS_MIN_DUTY_CYCLE, D5_HEAT_TX_P_COEFFICIENT, D5_HEAT_TX_I_COEFFICIENT, + HEATERS_MIN_DUTY_CYCLE, AC_HEATER_TX_MAX_DUTY_CYCLE, TRUE, D5_HEAT_TX_INIT_FEED_FORWARD ); // Initialize the trimmer heater PI controller initializePIController( PI_CONTROLLER_ID_D45_HEAT, HEATERS_MIN_DUTY_CYCLE, D45_HEAT_P_COEFFICIENT, D45_HEAT_I_COEFFICIENT, - HEATERS_MIN_DUTY_CYCLE, HEATERS_MAX_DUTY_CYCLE ); + HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE, FALSE, D45_HEAT_TX_INIT_FEED_FORWARD ); +#ifdef __HEATERS_DEBUG__ + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = 0.0F; + } +#endif + // Initialize the persistent alarms //initPersistentAlarm( ALARM_ID_DD_D5_HEAT_VOLTAGE_OUT_OF_RANGE, 0, HEATERS_VOLTAGE_OUT_OF_RANGE_TIMEOUT_MS ); //initPersistentAlarm( ALARM_ID_DD_D45_HEAT_VOLTAGE_OUT_OF_RANGE, 0, HEATERS_VOLTAGE_OUT_OF_RANGE_TIMEOUT_MS ); @@ -220,6 +281,22 @@ /*********************************************************************//** * @brief + * The getHeaterPWMPeriod function returns the given heater PWM + * period. + * @details \b Inputs: none + * @details \b Outputs: pwmPeriod + * @param heater: heater ID to get heater PWM period. + * @return the given heater PWM period. + *************************************************************************/ +F32 getHeaterPWMPeriod( DD_HEATERS_T heater ) +{ + F32 pwmPrd = getF32OverrideValue( &pwmPeriod[ heater ] ); + + return pwmPrd; +} + +/*********************************************************************//** + * @brief * The isHeaterOn function returns the given heater status whether * it is on or off * @details \b Inputs: heaterStatus @@ -234,6 +311,28 @@ /*********************************************************************//** * @brief + * The signalHeaterControlOnQDUpdate function updates heater control based on + * the latest treatment paratmeter (Dialysate Flow rate) change + * @details \b Inputs: heatersStatus + * @details \b Outputs: none + * @param heater: heater ID to update the heater control. + * @return none + *************************************************************************/ +void signalHeaterControlOnQDUpdate( DD_HEATERS_T heater ) +{ + if ( D5_HEAT == heater ) + { + // check heater state + if ( HEATER_EXEC_STATE_CONTROL_TO_TARGET == heatersStatus[ heater ].state ) + { + // Set flag to recalculate the feedforward signals + startupHeaterControl = TRUE; + } + } +} + +/*********************************************************************//** + * @brief * The startHeater function starts the given heater by setting the flag. * @details \b Inputs: heatersStatus * @details \b Outputs: startHeaterSignal @@ -270,10 +369,13 @@ { if( heater < NUM_OF_DD_HEATERS ) { - heatersStatus[ heater ].startHeaterSignal = FALSE; - heatersStatus[ heater ].heaterOnState = FALSE; - control[ heater ].data = HEATERS_MIN_DUTY_CYCLE; - heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; + heatersStatus[ heater ].startHeaterSignal = FALSE; + heatersStatus[ heater ].heaterOnState = FALSE; + control[ heater ].data = HEATERS_MIN_DUTY_CYCLE; + heatersStatus[ heater ].state = HEATER_EXEC_STATE_OFF; + heatersStatus[ D5_HEAT ].controlIntervalCounter = D5_HEAT_CONTROL_INTERVAL_START_COUNT; + heatersStatus[ D45_HEAT ].controlIntervalCounter = 0; + startupHeaterControl = TRUE; // update duty cycle setHeaterControl( heater ); @@ -355,22 +457,16 @@ ALARM_ID_T alarm; BOOL isLevelLow = FALSE; - switch ( heater ) + if ( D5_HEAT == heater ) { - case D5_HEAT: - alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_D5_HEAT_IS_ON; - isLevelLow = ( ( getLevelStatus( D6_LEVL ) != 0 )? FALSE : TRUE ); - break; - - case D45_HEAT: - alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_D45_HEAT_IS_ON; - isLevelLow = ( ( getLevelStatus( D46_LEVL ) != 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; + alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_D5_HEAT_IS_ON; + isLevelLow = ( ( getLevelStatus( D6_LEVL ) != 0 )? FALSE : TRUE ); } + else + { + alarm = ALARM_ID_DD_FLUID_TOO_LOW_WHILE_D45_HEAT_IS_ON; + isLevelLow = ( ( getLevelStatus( D46_LEVL ) != 0 )? FALSE : TRUE ); + } checkPersistentAlarm( alarm, isLevelLow, 0.0F, 0.0F ); } @@ -412,7 +508,7 @@ heatersStatus[ heater ].heaterOnState = TRUE; heatersStatus[ heater ].startHeaterSignal = FALSE; - // proceed to ramp state + // proceed to setup state state = HEATER_EXEC_STATE_RAMP_TO_TARGET; } @@ -425,22 +521,36 @@ * 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. + * @param heater: The heater Id to handle the initial setup control for heater. * @return next state of the state machine *************************************************************************/ static HEATERS_STATE_T handleHeaterStateRampToTarget( DD_HEATERS_T heater ) { - HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; - F32 ctrl = 0.0F; - DD_OP_MODE_T opMode = getCurrentOperationMode(); - F32 targetTemperature = getHeaterTargetTemperature( heater ); + HEATERS_STATE_T state = HEATER_EXEC_STATE_RAMP_TO_TARGET; + F32 ctrl = 0.0F; + DD_OP_MODE_T opMode = getCurrentOperationMode(); + F32 measuredTemperature = 0.0F; + F32 targetTemperature = getHeaterTargetTemperature( heater ); if ( D5_HEAT == heater ) { + measuredTemperature = getTemperatureValue( D4_TEMP ); + if ( DD_MODE_HEAT != opMode ) { - control[ heater ].data = D5_HEAT_ON; - state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + F32 deltaTempC = targetTemperature - measuredTemperature; + F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); + + if ( capDeltaTempC <= HEATER_TEMP_CONTROL_TRANSFER ) + { + // Transfer Control to target when delta temp is minimal. + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; + } + else + { + // Start Open loop control with max power + control[ heater ].data = AC_HEATER_TX_MAX_DUTY_CYCLE; + } } else { @@ -450,9 +560,19 @@ } else { + measuredTemperature = getTemperatureValue( D50_TEMP ); + if ( DD_MODE_HEAT != opMode ) { - ctrl = ( ( targetTemperature / HEATER_TARGET_TEMPERATURE_MAX ) * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; + F32 deltaTempC = targetTemperature - measuredTemperature; + F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); + F32 flowrate = getTDDialysateFlowrate() / LITER_IN_ML ; + F32 dutyCycle = calculateDutyCycle( flowrate, capDeltaTempC, TRIMMER_HEATER_MAX_PWR_WATTS, DC_HEATER_EFFICIENCY, + HEATERS_MIN_DUTY_CYCLE, DC_HEATER_MAX_DUTY_CYCLE ); + + control[ heater ].data = dutyCycle; + resetPIController( PI_CONTROLLER_ID_D45_HEAT, dutyCycle, D45_HEAT_TX_INIT_FEED_FORWARD ); + state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; } else @@ -484,47 +604,59 @@ { HEATERS_STATE_T state = HEATER_EXEC_STATE_CONTROL_TO_TARGET; F32 targetTemperature = getHeaterTargetTemperature( heater ); + F32 inletTemperature = 0.0F; F32 measuredTemperature = 0.0F; F32 ctrl = 0.0F; - if( ++heatersStatus[ heater ].controlIntervalCounter > D5_HEAT_CONTROL_INTERVAL_COUNT ) + if( ++heatersStatus[ heater ].controlIntervalCounter > controlInterval[ heater ] ) { - switch ( heater ) + if ( D5_HEAT == heater ) { - case D5_HEAT: - measuredTemperature = getTemperatureValue( (U32)D4_TEMP ); - if ( measuredTemperature >= targetTemperature ) - { - // Turn off heater - control[ heater ].data = HEATERS_MIN_DUTY_CYCLE; - } - else - { - // Turn On heater - control[ heater ].data = D5_HEAT_ON; - } + measuredTemperature = getTemperatureValue( D4_TEMP ); + // Inlet temperature post heat exchanger + inletTemperature = getTemperatureValue( X6_TEMP ); - //control = runPIController( PI_CONTROLLER_ID_D5_HEAT, targetTemperature, measuredTemperature ); - break; + if ( TRUE == startupHeaterControl ) + { + startupHeaterControl = FALSE; + //TODO : testing + //F32 deltaTempC = targetTemperature - inletTemperature; + F32 deltaTempC = 10.0F; // Hard code for testing, later remove it. + F32 capDeltaTempC = MAX( deltaTempC, HEATERS_ZERO_DELTA_TEMP_C ); + F32 flowrate = getTDDialysateFlowrate() / LITER_IN_ML ; + F32 feedforward = calculateDutyCycle( flowrate, capDeltaTempC, PRIMARY_HEATER_MAX_PWR_WATTS, AC_HEATER_EFFICIENCY, + HEATERS_MIN_DUTY_CYCLE, AC_HEATER_TX_MAX_DUTY_CYCLE ); + control[ heater ].data = feedforward; + resetPIController( PI_CONTROLLER_ID_D5_HEAT, HEATERS_MIN_DUTY_CYCLE, feedforward ); + } + else + { + ctrl = runPIController( PI_CONTROLLER_ID_D5_HEAT, targetTemperature, measuredTemperature ); + control[ heater ].data = ctrl; + } +#ifdef __HEATERS_DEBUG__ + U32 i; - case D45_HEAT: - measuredTemperature = getTemperatureValue( (U32)D50_TEMP ); - //control = runPIController( PI_CONTROLLER_ID_D45_HEAT, targetTemperature, measuredTemperature ); - if ( targetTemperature > 0.0F ) - { - ctrl = HEATERS_MAX_DUTY_CYCLE - ( measuredTemperature / targetTemperature ); - ctrl = ( ctrl < 0.0F ? HEATERS_MIN_DUTY_CYCLE: ctrl * D45_HEAT_GAIN ); - //Apply dutycycle limit - ctrl = MIN( ctrl, HEATERS_MAX_DUTY_CYCLE ); - ctrl = MAX( ctrl, HEATERS_MIN_DUTY_CYCLE ); - } + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D5_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); + } +#endif + } + else + { + measuredTemperature = getTemperatureValue( D50_TEMP ); - control[ heater ].data = ( ctrl * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; - break; + ctrl = runPIController( PI_CONTROLLER_ID_D45_HEAT, targetTemperature, measuredTemperature ); + control[ heater ].data = ctrl; +#ifdef __HEATERS_DEBUG__ + U32 i; - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_HEATERS_INVALID_HEATER_ID_SELECTED, heater ) - break; + for ( i = 0; i < NUM_OF_CONTROLLER_SIGNAL; i++ ) + { + pIControlSignal[ i ] = getPIControllerSignals( PI_CONTROLLER_ID_D45_HEAT, (PI_CONTROLLER_SIGNALS_ID)i ); + } +#endif } heatersStatus[ heater ].hasTargetTempChanged = FALSE; @@ -572,18 +704,22 @@ { if ( heater < NUM_OF_DD_HEATERS ) { - F32 control; + F32 control = getHeaterControl( heater ); + F32 period = getHeaterPWMPeriod ( heater ); - control = getHeaterControl( heater ); - if ( D5_HEAT == heater ) { - BOOL heaterCntrl = (BOOL)control; - setFPGACPrimaryHeaterOnOffControl( heaterCntrl ); + //Convert duty cycle into LowState and multiply by period + F32 duty = AC_HEATER_MAX_DUTY_CYCLE - control; + convertDC = duty * period; + + setFPGAD5HeaterPWMPeriod( (U16)period ); + setFPGAD5HeaterPWMLowState( (U16)convertDC ); } else { - setFPGATrimmerHeaterPWMControl( (U08)control ); + U08 ctrl = ( control * HEATERS_DUTY_CYCLE_CONVERSION_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET; + setFPGAD45HeaterPWMControl( ctrl ); } } else @@ -609,6 +745,37 @@ /*********************************************************************//** * @brief + * The calculateDutyCycle function calculates the heater's duty cycle + * based on the delta temperature, flowrate and power applied to the heater. + * @details \b Inputs: none + * @details \b Outputs: duty cycle + * @param flowrate: dialysate flowrate. + * @param deltaTemp: Temperature difference between actual and target. + * @param power: Power supplied to the heater + * @param efficiency: Heater efficeincy to compensate heatloss + * @param min: heaters minimum duty cycle + * @param max: heaters maximum duty cycle + * @return calcualted PWM duty cycle + *************************************************************************/ +static F32 calculateDutyCycle( F32 flowrate, F32 deltaTemp, F32 power, F32 efficiency, F32 min, F32 max ) +{ + F32 duty = ( WATER_SPECIFIC_HEAT_DIVIDED_BY_MINUTES * deltaTemp * flowrate ) / power; + + // Updated duty with efficiency + if ( HEATERS_ZERO_EFFICIENCY != efficiency ) + { + duty = duty / efficiency; + } + + // Apply min/max limits + duty = MIN( duty, max ); + duty = MAX( duty, min ); + + return duty; +} + +/*********************************************************************//** + * @brief * The monitorHeatersVoltage function monitors the heaters' voltages * @details \b Inputs: Voltage range * @details \b Outputs: none @@ -669,8 +836,24 @@ data.d45_HeaterTargetTemp = getHeaterTargetTemperature( D45_HEAT ); data.d5_HeaterState = heatersStatus[ D5_HEAT ].state; data.d45_HeaterState = heatersStatus[ D45_HEAT ].state; +#ifndef __HEATERS_DEBUG__ data.d5_HeaterControlCounter = heatersStatus[ D5_HEAT ].controlIntervalCounter; data.d45_HeaterControlCounter = heatersStatus[ D45_HEAT ].controlIntervalCounter; +#else + data.d5_HeaterControlCounter = (U32)convertDC; + data.d45_HeaterControlCounter = (U32)getHeaterPWMPeriod( D5_HEAT ); +#endif +#ifdef __HEATERS_DEBUG__ + data.dbg1 = pIControlSignal[ 0 ]; + data.dbg2 = pIControlSignal[ 1 ]; + data.dbg3 = pIControlSignal[ 2 ]; + data.dbg4 = pIControlSignal[ 3 ]; + data.dbg5 = pIControlSignal[ 4 ]; + data.dbg6 = pIControlSignal[ 5 ]; + data.dbg7 = pIControlSignal[ 6 ]; + data.dbg8 = pIControlSignal[ 7 ]; + data.dbg9 = pIControlSignal[ 8 ]; +#endif dataPublicationTimerCounter = 0; @@ -737,6 +920,23 @@ /*********************************************************************//** * @brief + * The testHeaterPWMPeriodOverride function overrides the specified heater's + * PWM period. + * @details \b Inputs: pwmPeriod + * @details \b Outputs: pwmPeriod + * @param message Override message from Dialin which includes an ID of + * the heater to override and the PWM period of the heater. + * @return TRUE if the override was successful otherwise FALSE + *************************************************************************/ +BOOL testHeaterPWMPeriodOverride( MESSAGE_T *message ) +{ + BOOL result = f32ArrayOverride( message, &pwmPeriod[ 0 ], NUM_OF_DD_HEATERS - 1 ); + + return result; +} + +/*********************************************************************//** + * @brief * The testHeaterStartStopOverride function starts/stops a given heater * at mentioned temperature. * @details \b Inputs: tester logged in @@ -749,7 +949,7 @@ { BOOL result = FALSE; - // Verify tester has logged in with TD + // Verify tester has logged in with DD if ( TRUE == isTestingActivated() ) { // Verify payload length is valid Index: firmware/App/Controllers/PistonPumpControl.h =================================================================== diff -u -r2ef70ec14fb47bee35cb241a927582f7ccd1bb22 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Controllers/PistonPumpControl.h (.../PistonPumpControl.h) (revision 2ef70ec14fb47bee35cb241a927582f7ccd1bb22) +++ firmware/App/Controllers/PistonPumpControl.h (.../PistonPumpControl.h) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -14,12 +14,11 @@ * @date (original) 07-Jan-2025 * ***************************************************************************/ +#ifdef __PUMPTEST__ #ifndef __PISTON_PUMP_CONTROL_H__ #define __PISTON_PUMP_CONTROL_H__ -#ifdef __PUMPTEST__ - #include "DDCommon.h" #include "DDDefs.h" @@ -63,9 +62,11 @@ void execPistonPumpController( void ); // Execute the piston pump control state machine void startPistonPumpCycle( PISTON_PUMPS_T pumpId, U32 cycleCount, F32 targetVolume_ml, F32 speed ); // Set the piston pump parameters void stopPistonPumpCycle( PISTON_PUMPS_T pumpId ); // Stop the piston pump +void processPistonPumpDosingTrigger( void ); // Process doding pump trigger control BOOL testDDPistonPumpControlDataPublishIntervalOverride( MESSAGE_T *message ); // To override the piston pump control data publish interval BOOL testDDPistonPumpStartStopOverride( MESSAGE_T *message ); // To override the piston pump start/stop control +BOOL testDDPistonPumpFillAfterDispenseOverride( MESSAGE_T *message ); // To override the piston pump fill after dispense control /**@}*/ Index: firmware/App/DDCommon.h =================================================================== diff -u -r597c1b8b790357bdcacb3a50ae4b5e4278ba7a88 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/DDCommon.h (.../DDCommon.h) (revision 597c1b8b790357bdcacb3a50ae4b5e4278ba7a88) +++ firmware/App/DDCommon.h (.../DDCommon.h) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -22,10 +22,10 @@ // ********** version ********** -#define DD_VERSION_MAJOR 0 -#define DD_VERSION_MINOR 0 -#define DD_VERSION_MICRO 0 -#define DD_VERSION_BUILD 0 +#define DD_VERSION_MAJOR 0 +#define DD_VERSION_MINOR 0 +#define DD_VERSION_MICRO 0 +#define DD_VERSION_BUILD 1 //Uncomment the below line for new dosing pump testing //#define __PUMPTEST__ 1 @@ -39,6 +39,22 @@ #ifndef _VECTORCAST_ // #define TASK_TIMING_OUTPUT_ENABLED 1 // Re-purposes alarm lamp pins for task timing +//flag to check PT100 use in calculations +//#define USE_PT_100 1 + +//Uncomment the below line for new dosing pump testing +//#define __PUMPTEST__ 1 + +//Uncomment below line for future hardware version +//#define __ALPHA_AO_VER__ 1 + +//Uncomment below for dialysate pump PI testing +//#define __PITEST__ 1 + +//Uncomment below to disable heaters debug message +#define __HEATERS_DEBUG__ 1 + + #include #include #endif Index: firmware/App/Drivers/TemperatureSensors.c =================================================================== diff -u -r3b6bf2cb6d15da8cb273cff109d2c4b1ee99d546 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 3b6bf2cb6d15da8cb273cff109d2c4b1ee99d546) +++ firmware/App/Drivers/TemperatureSensors.c (.../TemperatureSensors.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -40,9 +40,11 @@ #define PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE 20000 ///< Primary heater temperature sensors reference resistance. #define PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE 1000U ///< Primary heater temperature sensors zero degree resistance. -#define PT100_TEMP_SENSORS_GAIN 8U ///< PT100 temperature sensors gain. +#ifdef USE_PT_100 +#define PT100_TEMP_SENSORS_GAIN 8U ///< PT100 temperature sensors gain. #define PT100_TEMP_SENSORS_REF_RESISTANCE 4700 ///< PT100 temperature sensors reference resistance. #define PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE 100U ///< PT100 temperature sensors zero degree resistance. +#endif #define TEMP_SENSORS_ADC_BITS 24U ///< External temperature sensors ADC bits. #define MAX_NUM_OF_RAW_ADC_SAMPLES 4U ///< Number of ADC reads for moving average calculations. @@ -198,7 +200,6 @@ tempSensors[ D50_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; #endif - // Board temperature sensors conversion coefficient tempSensors[ BRD_TEMP ].conversionCoeff = conversionCoeff; tempSensors[ BRD_TEMP ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; @@ -607,7 +608,7 @@ //calId = NUM_OF_CAL_DATA_TEMP_SENSORS; break; } - + //TODO : Enable the code later when calibration data available. // if ( calId != NUM_OF_CAL_DATA_TEMP_SENSORS ) // { // *temperature = pow( tempTemperature, 4 ) * tempSensorCalRecord.tempSensors[ calId ].fourthOrderCoeff + Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rf5baeac6a5f000705cd51e4779a967acf4088981 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision f5baeac6a5f000705cd51e4779a967acf4088981) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -43,7 +43,7 @@ static DD_STANDBY_MODE_STATE_T standbyState; ///< Currently active standby state. -static OVERRIDE_U32_T pendingStartDDRequest; ///< Flag indicating TD has requested DD start the dialysis delivery(Overridable). +static OVERRIDE_U32_T pendingStartDDPreGenRequest; ///< Flag indicating TD has requested DD start the pre generation dialysate request(Overridable). static BOOL pendingBalanceChamberSwOnlyRequest; ///< Flag indicating balancing chamber switch only request. //static BOOL pendingStartDDFlushRequest; ///< Flag indicating TD has requested DD start flush. //static BOOL pendingStartDDHeatDisinfectRequest; ///< Flag indicating TD has requested DD start heat disinfect. @@ -65,10 +65,10 @@ void initStandbyMode( void ) { standbyState = DD_STANDBY_MODE_STATE_IDLE; - pendingStartDDRequest.data = FALSE; - pendingStartDDRequest.ovData = FALSE; - pendingStartDDRequest.ovInitData = FALSE; - pendingStartDDRequest.override = OVERRIDE_RESET; + pendingStartDDPreGenRequest.data = FALSE; + pendingStartDDPreGenRequest.ovData = FALSE; + pendingStartDDPreGenRequest.ovInitData = FALSE; + pendingStartDDPreGenRequest.override = OVERRIDE_RESET; pendingBalanceChamberSwOnlyRequest = FALSE; // pendingStartDDFlushRequest = FALSE; // pendingStartDDHeatDisinfectRequest = FALSE; @@ -173,7 +173,7 @@ * @brief * The handleStandbyIdleState function executes the idle state of the * standby mode state machine. - * @details \b Inputs: pendingSampleWaterRequest, pendingStartDDRequest, + * @details \b Inputs: pendingSampleWaterRequest, pendingStartDDPreGenRequest, * pendingStartDDFlushRequest, pendingStartDDHeatDisinfectRequest, * pendingStartDDChemicalDisinfectRequest * @details \b Outputs: Idle state of the standby mode executed, @@ -187,26 +187,26 @@ { DD_STANDBY_MODE_STATE_T state = DD_STANDBY_MODE_STATE_IDLE; - //TODO : Testing - commenting solo mode for now - - // go to standby solo mode if TD is turned off or stops communicating. + //TODO : Define comm loss alarm when TD is turned off or stops communicating // if ( FALSE == isTDCommunicating() ) -// { // TODO if TD comm loss, do we need solo standby? -// SEND_EVENT_WITH_2_U32_DATA( DD_EVENT_TD_COMMUNICATION_LOSS, 0, 0 ) -// //requestNewOperationMode( DD_MODE_SOLO ); +// { + // define the alarm // } -// else if ( TRUE == getU32OverrideValue( &pendingStartDDRequest ) ) - - if ( TRUE == getU32OverrideValue( &pendingStartDDRequest ) ) + if ( TRUE == getU32OverrideValue( &pendingStartDDPreGenRequest ) ) { - pendingStartDDRequest.data = FALSE; - requestNewOperationMode( DD_MODE_GEND ); + pendingStartDDPreGenRequest.data = FALSE; + requestNewOperationMode( DD_MODE_PREG ); } //Test request to handle only balancing chamber switching else if ( TRUE == pendingBalanceChamberSwOnlyRequest ) { execBalancingChamberControl(); } + //Test request to handle only balancing chamber switching + else if ( TRUE == pendingBalanceChamberSwOnlyRequest ) + { + execBalancingChamberControl(); + } // else if ( TRUE == pendingStartDDFlushRequest ) // { // pendingStartDDFlushRequest = FALSE; @@ -253,19 +253,20 @@ /*********************************************************************//** * @brief - * The requestDDStart function handles an TD request to start (go to generation dialysis mode). + * The requestDDPreGenStart function handles an TD request to start/ + * go to pre generation dialysis mode. * @details \b Inputs: standbyState - * @details \b Outputs: pendingStartDDRequest + * @details \b Outputs: pendingStartDDPreGenRequest * @return TRUE if request accepted, FALSE if not. *************************************************************************/ -BOOL requestDDStart( void ) +BOOL requestDDPreGenStart( void ) { BOOL result = FALSE; if ( DD_STANDBY_MODE_STATE_IDLE == standbyState ) { - result = TRUE; - pendingStartDDRequest.data = TRUE; + result = TRUE; + pendingStartDDPreGenRequest.data = TRUE; } return result; @@ -508,17 +509,17 @@ /*********************************************************************//** * @brief - * The testDDstartGenDialysateOverride function sets the override value - * to start the gen dialysate operation mode. - * @details Inputs: pendingStartDDRequest - * @details Outputs: pendingStartDDRequest + * The testDDStartPreGenDialysateOverride function sets the override value + * to start the pre-gen dialysate operation mode. + * @details Inputs: pendingStartDDPreGenRequest + * @details Outputs: pendingStartDDPreGenRequest * @param message Override message from Dialin which includes the flag * to override the operation mode. * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testDDstartGenDialysateOverride( MESSAGE_T *message ) +BOOL testDDStartPreGenDialysateOverride( MESSAGE_T *message ) { - BOOL result = u32Override( message, &pendingStartDDRequest, FALSE, TRUE ); + BOOL result = u32Override( message, &pendingStartDDPreGenRequest, FALSE, TRUE ); return result; } Index: firmware/source/sys_main.c =================================================================== diff -u -rf8bb43e62a4d10b64d8b197e372a56adfcfb88b9 -re12eefac42a3806a34f3ddac6df30bbb5ca51f6f --- firmware/source/sys_main.c (.../sys_main.c) (revision f8bb43e62a4d10b64d8b197e372a56adfcfb88b9) +++ firmware/source/sys_main.c (.../sys_main.c) (revision e12eefac42a3806a34f3ddac6df30bbb5ca51f6f) @@ -46,6 +46,7 @@ /* USER CODE END */ /* Include Files */ + #include "sys_common.h" /* USER CODE BEGIN (1) */