Index: firmware/App/Controllers/Fans.c =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/Fans.c (.../Fans.c) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Controllers/Fans.c (.../Fans.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -1,4 +1,5 @@ +#include "etpwm.h" #include "Fans.h" #include "TaskGeneral.h" #include "Thermistors.h" @@ -42,25 +43,24 @@ /// Fans exec states typedef enum fans_Exec_States { - FANS_EXEC_STATE_WAIT_FOR_POST = 0, ///< Fans exec state start - FANS_EXEC_STATE_RUN, ///< Fans exec state run - NUM_OF_FANS_EXEC_STATES, ///< Number of fans exec states + FANS_EXEC_STATE_WAIT_FOR_POST = 0, ///< Fans exec state start + FANS_EXEC_STATE_RUN, ///< Fans exec state run + NUM_OF_FANS_EXEC_STATES, ///< Number of fans exec states } FANS_EXEC_STATES_T; /// Fans status struct typedef struct { F32 targetDutyCycle; ///< Fan's target duty cycle that was fed to the fans - F32 previousDutyCycle; ///< Fan's previous duty cycle from calculation U32 rpm[ NUM_OF_FANS_NAMES ]; ///< Fan's current tachometers reading in RPM } FAN_STATUS_T; -static FAN_STATUS_T fansStatus; ///< Fans status -static SELF_TEST_STATUS_T fansSelfTestReslt = SELF_TEST_STATUS_IN_PROGRESS; ///< Fans self test result -static FANS_SELF_TEST_STATES_T fansSelfTestState = FANS_SELF_TEST_START; ///< Fans self test state -static FANS_EXEC_STATES_T fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST; ///< Fans exec state -static U32 fansControlCounter = 0; ///< Fans control interval counter -static U32 fansPublishCounter = 0; ///< Fans data publish interval counter +static FAN_STATUS_T fansStatus; ///< Fans status +static SELF_TEST_STATUS_T fansSelfTestReslt = SELF_TEST_STATUS_IN_PROGRESS; ///< Fans self test result +static FANS_SELF_TEST_STATES_T fansSelfTestState = FANS_SELF_TEST_START; ///< Fans self test state +static FANS_EXEC_STATES_T fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST; ///< Fans exec state +static U32 fansControlCounter = 0; ///< Fans control interval counter +static U32 fansPublishCounter = 0; ///< Fans data publish interval counter /// Temperature to duty cycle conversion slope (duty cycle not in percent) static const F32 slope = ( FANS_MAX_DUTY_CYCLE - FANS_MIN_DUTY_CYCLE ) / ( MAX_ALLOWED_AMBINET_TEMPERATURE - MIN_ALLOWED_AMBIENT_TEMPERATURE ); @@ -316,11 +316,11 @@ // If the fans calculated duty cycle is greater than the previous calculated duty cycle, we are ramping up // otherwise, we are ramping down - if ( dutyCycle >= fansStatus.previousDutyCycle ) + if ( dutyCycle >= fansStatus.targetDutyCycle ) { // If the delta duty cycle from the previous duty cycle is greater than the max allowed ramp up duty cycle, // otherwise, only add the delta duty cycle - if ( ( dutyCycle - fansStatus.previousDutyCycle ) >= FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE ) + if ( ( dutyCycle - fansStatus.targetDutyCycle ) >= FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE ) { fansStatus.targetDutyCycle += FANS_MAX_ALLOWED_RAMP_UP_DELTA_DUTY_CYCLE; } @@ -335,9 +335,6 @@ fansStatus.targetDutyCycle -= FANS_MAX_ALLOWED_RAMP_DOWN_DELTA_DUTY_CYCLE; } - // Update the structure - fansStatus.previousDutyCycle = dutyCycle; - // Set the PWM to inlet and outlet fans setInletFansPWM( fansStatus.targetDutyCycle ); setOutletFansPWM( fansStatus.targetDutyCycle ); @@ -500,7 +497,6 @@ { FANS_DATA_T fansData; - fansData.fansCalculatedPWM = fansStatus.previousDutyCycle * 100; fansData.fansTargetPWM = fansStatus.targetDutyCycle * 100; fansData.fanInlet1RPM = fansStatus.rpm[ FAN_INLET_1 ]; fansData.fanInlet2RPM = fansStatus.rpm[ FAN_INLET_2 ]; Index: firmware/App/Controllers/Fans.h =================================================================== diff -u -r2f2d0ccadd8a09037eb3d0dd144549b2c8c8129b -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/Fans.h (.../Fans.h) (revision 2f2d0ccadd8a09037eb3d0dd144549b2c8c8129b) +++ firmware/App/Controllers/Fans.h (.../Fans.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -2,7 +2,6 @@ #ifndef _FANS_H_ #define _FANS_H_ -#include "etpwm.h" #include "Common.h" /** @@ -28,7 +27,6 @@ /// Fans data publish typedef struct { - F32 fansCalculatedPWM; ///< Fans calculated PWM F32 fansTargetPWM; ///< Fans target PWM F32 fanInlet1RPM; ///< Fan inlet 1 RPM F32 fanInlet2RPM; ///< Fan inlet 2 RPM Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r1f500f8e6159a3fbab85ea68389e918a6df66400 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 1f500f8e6159a3fbab85ea68389e918a6df66400) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -45,9 +45,8 @@ #define RO_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the RO Pump data is published on the CAN bus. -#define MAX_RO_PUMP_PWM_STEP_CHANGE 0.01 ///< max duty cycle change for controller. -#define MAX_RO_PUMP_PWM_DUTY_CYCLE 0.99 ///< max duty cycle. -#define MIN_RO_PUMP_PWM_DUTY_CYCLE 0.00 ///< min duty cycle. +#define MAX_RO_PUMP_DUTY_CYCLE 0.99 ///< max duty cycle. +#define MIN_RO_PUMP_DUTY_CYCLE 0.1 ///< min duty cycle. #define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< interval (ms/task time) at which the RO pump is controlled. #define ROP_P_COEFFICIENT 0.0020 ///< P term for RO pump pressure control. @@ -66,21 +65,16 @@ #define RO_FLOW_ADC_TO_LPM_FACTOR 10909.0909 ///< conversion factor from ADC counts to LPM (liters/min) for RO flow rate (multiply this by inverse of FPGA reading). #define ROP_FLOW_TO_PWM_DC(flow) ( (F32)( flow / MAX_RO_FLOWRATE_LPM ) ) ///< Initial conversion factor from target flow rate to PWM duty cycle estimate. - -/* TODO remove -#define MAX_RO_PUMP_PWM_STEP_CHANGE 0.01 ///< Max duty cycle change for controller. -#define MAX_RO_PUMP_PWM_DUTY_CYCLE 0.99 ///< Max duty cycle. -#define MIN_RO_PUMP_PWM_DUTY_CYCLE 0.00 ///< Min duty cycle. -#define ROP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the RO pump is controlled. -#define ROP_P_COEFFICIENT 0.0020 ///< P term for RO pump control. -#define ROP_I_COEFFICIENT 0.0015 ///< I term for RO pump control. -*/ - #define FLOW_SENSOR_ZERO_READING 0xFFFF ///< Flow sensor reading indicates zero flow (or flow lower than can be detected by sensor). #define FLOW_SAMPLES_TO_AVERAGE ( 250 / TASK_PRIORITY_INTERVAL ) ///< Averaging flow data over 250 ms intervals. -#define FLOW_AVERAGE_MULTIPLIER ( 1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing. +#define FLOW_AVERAGE_MULTIPLIER ( 1.0 / (F32)FLOW_SAMPLES_TO_AVERAGE ) ///< Optimization - multiplying is faster than dividing. +#define MAX_ALLOWED_FLOW_DEVIATION 0.1 ///< Max allowed deviation from target flow. +#define FLOW_OUT_OF_RANGE_TIME_OUT ( 5000 / TASK_PRIORITY_INTERVAL ) ///< Flow out of range time out in counts. +#define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. +#define MAX_ALLOWED_PRESSURE_PSI 140 ///< Maximum allowed pressure that the RO pump can go to. +#define MIN_ALLOWED_PRESSURE_PSI 10 ///< Minimum allowed pressure that the RO pump can go to. // TODO - this is a place holder for real conversion #define ROP_PSI_TO_PWM_DC(p) ( 0.2 + ( (F32)((p) - 100) * 0.01 ) ) ///< conversion factor from target PSI to PWM duty cycle estimate. @@ -114,37 +108,37 @@ // ********** private data ********** -static RO_PUMP_STATE_T roPumpState = RO_PUMP_OFF_STATE; ///< current state of RO pump controller state machine -static U32 roPumpDataPublicationTimerCounter = 0; ///< used to schedule RO pump data publication to CAN bus -static BOOL isROPumpOn = FALSE; ///< RO pump is currently running -static F32 roPumpPWMDutyCyclePct = 0.0; ///< initial RO pump PWM duty cycle -static F32 roPumpPWMDutyCyclePctSet = 0.0; ///< currently set RO pump PWM duty cycle -static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested RO pump control mode -static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set RO pump control mode +static RO_PUMP_STATE_T roPumpState = RO_PUMP_OFF_STATE; ///< current state of RO pump controller state machine +static U32 roPumpDataPublicationTimerCounter = 0; ///< used to schedule RO pump data publication to CAN bus +static BOOL isROPumpOn = FALSE; ///< RO pump is currently running +static F32 roPumpPWMDutyCyclePct = 0.0; ///< initial RO pump PWM duty cycle +static F32 roPumpDutyCyclePctSet = 0.0; ///< currently set RO pump PWM duty cycle +static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< requested RO pump control mode +static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< currently set RO pump control mode -static OVERRIDE_F32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; ///< Target RO flow rate (in LPM) +static OVERRIDE_F32_T targetROPumpFlowRate = { 0, 0, 0, 0 }; ///< Target RO flow rate (in LPM) static OVERRIDE_U32_T roPumpDataPublishInterval = { RO_PUMP_DATA_PUB_INTERVAL, RO_PUMP_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish RO flow data to CAN bus -static OVERRIDE_F32_T measuredROFlowRateLPM = { 0.0, 0.0, 0.0, 0 }; ///< measured RO flow rate (in LPM) + 0, 0 }; ///< Interval (in ms) at which to publish RO flow data to CAN bus +static OVERRIDE_F32_T measuredROFlowRateLPM = { 0.0, 0.0, 0.0, 0 }; ///< measured RO flow rate (in LPM) -static U32 flowVerificationCounter = 0; ///< Counter to verify the flow is in range +static U32 flowVerificationCounter = 0; ///< Counter to verify the flow is in range -static U32 roControlTimerCounter = 0; ///< determines when to perform control on RO pump +static U32 roControlTimerCounter = 0; ///< determines when to perform control on RO pump -static F32 roPumpOpenLoopTargetPWM = 0; ///< Target RO pump open loop PWM -static F32 roPumpFlowRateRunningSum = 0; ///< RO pump flow rate running sum -static F32 roPumpPressureRunningSum = 0; ///< RO pump pressure running sum +static F32 roPumpOpenLoopTargetDutyCycle = 0; ///< Target RO pump open loop PWM +static F32 roPumpFlowRateRunningSum = 0; ///< RO pump flow rate running sum +static F32 roPumpPressureRunningSum = 0; ///< RO pump pressure running sum + +static RO_PUMP_SELF_TEST_STATE_T roPumpSelfTestState = RO_PUMP_SELF_TEST_STATE_START; ///< current ro pump self test state +static U32 roPumpSelfTestTimerCount = 0; ///< timer counter for ro pump self test -/* The variables used for POST. They are not in use yet, so they are commented out -static RO_PUMP_SELF_TEST_STATE_T roPumpSelfTestState = RO_PUMP_SELF_TEST_STATE_START; ///< current ro pump self test state -static U32 roPumpSelfTestTimerCount = 0; ///< timer counter for ro pump self test -*/ - -static OVERRIDE_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI). +static OVERRIDE_U32_T targetROPumpPressure = { 0, 0, 0, 0 }; ///< Target RO pressure (in PSI) -static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging. -static U32 flowFilterCounter = 0; ///< Flow filtering counter. +static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging +static U32 flowFilterCounter = 0; ///< Flow filtering counter +static BOOL hasTargetFlowBeenReached = FALSE; ///< Flow set flag +static U32 flowOutOfRangeCounter = 0; // ********** private function prototypes ********** @@ -154,70 +148,70 @@ static RO_PUMP_STATE_T handleROPumpControlToTargetState( void ); static RO_PUMP_STATE_T handleROPumpOpenLoopState( void ); -static BOOL setROPumpTargetPressure( U32 roPressure, PUMP_CONTROL_MODE_T mode ); -static BOOL setROPumpTargetPWM( F32 pwm ); -static void setROPumpControlSignalPWM( F32 newPWM ); +static BOOL setROPumpTargetPressure( U32 roPressure ); +static void setROPumpTargetDutyCycle( F32 duty ); +static void setROPumpControlSignalDutyCycle( F32 newPWM ); static void stopROPump( void ); static void publishROPumpData( void ); static U32 getPublishROPumpDataInterval( void ); /*********************************************************************//** * @brief - * The initROPump function initializes the ROPump module. - * @details - * Inputs: none - * Outputs: ROPump module initialized. + * The initROPump function initializes the RO Pump module. + * @details Inputs: hasTargetFlowBeenReached, flowOutOfRangeCounter + * @details Outputs: hasTargetFlowBeenReached, flowOutOfRangeCounter * @return none *************************************************************************/ void initROPump( void ) { stopROPump(); // Initialize RO pump PI controller - initializePIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_PWM_DUTY_CYCLE, + initializePIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_DUTY_CYCLE, ROP_P_COEFFICIENT, ROP_I_COEFFICIENT, - MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE ); + MIN_RO_PUMP_DUTY_CYCLE, MAX_RO_PUMP_DUTY_CYCLE ); - // Initialize the P controller during ramp up - initializePIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE, + // Initialize the I controller during ramp up + initializePIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_DUTY_CYCLE, ROP_RAMP_UP_P_COEFFICIENT, ROP_RAMP_UP_I_COEFFICIENT, - MIN_RO_PUMP_PWM_DUTY_CYCLE, MAX_RO_PUMP_PWM_DUTY_CYCLE ); + MIN_RO_PUMP_DUTY_CYCLE, MAX_RO_PUMP_DUTY_CYCLE ); + + // Make sure the flow set flag has been set to FALSE until it is set + hasTargetFlowBeenReached = FALSE; + flowOutOfRangeCounter = 0; } /*********************************************************************//** * @brief - * The setROPumpTargetPWM function sets the PWM that the pump should run - * @details - * Inputs: roPumpOpenLooptargetPWM, roPumpControlMode - * Outputs: roPumpOpenLooptargetPWM, roPumpControlMode - * @param: pwm - * @return whether the value was set (TRUE) or not (FALSE) + * The setROPumpTargetDutyCycle function sets the duty cycle that the + * pump should run. + * @details Inputs: roPumpOpenLoopTargetDutyCycle, roPumpPWMDutyCyclePct, + * roPumpPWMDutyCyclePctSet, roPumpControlMode + * @details Outputs: roPumpOpenLoopTargetDutyCycle, roPumpPWMDutyCyclePct, + * roPumpPWMDutyCyclePctSet, roPumpControlMode + * @param: duty which is the duty cycle + * @return none *************************************************************************/ -static BOOL setROPumpTargetPWM( F32 pwm ) +static void setROPumpTargetDutyCycle( F32 duty ) { - BOOL result = FALSE; - - if ( pwm >= MIN_RO_PUMP_PWM_DUTY_CYCLE && pwm < MAX_RO_PUMP_PWM_DUTY_CYCLE ) - { - roPumpOpenLoopTargetPWM = pwm; - roPumpPWMDutyCyclePct = roPumpOpenLoopTargetPWM; - roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; - roPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; - result = TRUE; - } - - return result; + roPumpOpenLoopTargetDutyCycle = duty; + roPumpPWMDutyCyclePct = roPumpOpenLoopTargetDutyCycle; + roPumpDutyCyclePctSet = roPumpPWMDutyCyclePct; + roPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; } /*********************************************************************//** * @brief - * The setROPumpTargetFlowRate function sets a new target flow rate for the \n + * The setROPumpTargetFlowRate function sets a new target flow rate for the * RO pump. - * @details - * Inputs: none - * Outputs: targetROPumpFlowRate, roPumpPWMDutyCyclePct - * @param: roFlowRate : new target RO flow rate - * @return TRUE if new target flow rate is set, FALSE if not + * @details Inputs: targetROPumpPressure, targetROPumpFlowRate, + * roPumpControlMode + * @details Outputs: targetROPumpPressure, targetROPumpFlowRate, + * roPumpControlMode + * @param roFlowRate which is target RO flow rate + * @param maxPressure which is the maximum allowed pressure that the RO pump + * can reach + * @return TRUE if new target flow rate is set successfully, FALSE if not *************************************************************************/ BOOL setROPumpTargetFlowRate( F32 roFlowRate, F32 maxPressure ) { @@ -247,31 +241,41 @@ /*********************************************************************//** * @brief - * The signalROPumpHardStop function stops the RO pump immediately. - * @details - * Inputs: none - * Outputs: RO pump stopped, set point reset, state changed to off + * The signalROPumpHardStop function stops the RO pump immediately and + * resets all the variables associated with the RO pump run. + * @details Inputs: targetROPumpFlowRate, roPumpState, roPumpPWMDutyCyclePct, + * roPumpOpenLoopTargetDutyCycle, roControlTimerCounter, flowVerificationCounter, + * flowVerificationCounter, isROPumpOn, hasTargetFlowBeenReached, + * flowOutOfRangeCounter + * @details Outputs: targetROPumpFlowRate, roPumpState, roPumpPWMDutyCyclePct, + * roPumpOpenLoopTargetDutyCycle, roControlTimerCounter, flowVerificationCounter, + * flowVerificationCounter, isROPumpOn, hasTargetFlowBeenReached, + * flowOutOfRangeCounter * @return none *************************************************************************/ void signalROPumpHardStop( void ) -{ - targetROPumpFlowRate.data = 0; - stopROPump(); - roPumpState = RO_PUMP_OFF_STATE; - roPumpPWMDutyCyclePct = 0.0; - roPumpOpenLoopTargetPWM = 0.0; - roControlTimerCounter = 0; - flowVerificationCounter = 0; - isROPumpOn = FALSE; - resetPIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_PWM_DUTY_CYCLE ); +{ + stopROPump(); + targetROPumpFlowRate.data = 0; + roPumpState = RO_PUMP_OFF_STATE; + roPumpPWMDutyCyclePct = 0.0; + roPumpOpenLoopTargetDutyCycle = 0.0; + roControlTimerCounter = 0; + flowVerificationCounter = 0; + isROPumpOn = FALSE; + hasTargetFlowBeenReached = FALSE; + flowOutOfRangeCounter = 0; + resetPIController( PI_CONTROLLER_ID_RO_PUMP, MIN_RO_PUMP_DUTY_CYCLE ); } /*********************************************************************//** * @brief - * The execROPumpMonitor function executes the RO Pump monitor. - * @details - * Inputs: none - * Outputs: measuredROPumpPressure, measuredROFlowRateLPM + * The execROPumpMonitor function executes the RO pump monitor. + * @details Inputs: measuredFlowReadingsSum, flowFilterCounter, + * measuredROFlowRateLPM, measuredROFlowRateLPM, hasTargetFlowBeenReached, + * flowOutOfRangeCounter, roPumpControlMode + * @details Outputs: measuredFlowReadingsSum, flowFilterCounter, + * measuredROFlowRateLPM, measuredROFlowRateLPM, flowOutOfRangeCounter * @return none *************************************************************************/ void execROPumpMonitor( void ) @@ -299,24 +303,47 @@ measuredFlowReadingsSum = 0; flowFilterCounter = 0; } + + // In order to check the flow rate deviation, the control mode must in closed loop and + // the target flow must have been set. There might be a time that the pump cannot reach to target flow + // and also it does not reach to maximum pressure. But after a certain timeout the flow will be set and the + // read flow will be checked to be in range. + if ( roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP && hasTargetFlowBeenReached ) + { + F32 currentFlow = getMeasuredROFlowRate(); + F32 targetFlow = getTargetROPumpFlowRate(); + F32 deviation = currentFlow / targetFlow; + + // If the flow is out of range for a certain amount of time in a row + if ( ++flowOutOfRangeCounter > FLOW_OUT_OF_RANGE_TIME_OUT && deviation > MAX_ALLOWED_FLOW_DEVIATION ) + { + // There are alarms for flow out of range and above the target or below the target + if ( currentFlow > targetFlow ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FLOW_RATE_OUT_OF_UPPER_RANGE, currentFlow, targetFlow ) + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_FLOW_RATE_OUT_OF_LOWER_RANGE, currentFlow, targetFlow ) + } + + } + // If the counter is > 0 but the deviation is in range again, reset the counter + else if ( flowOutOfRangeCounter > 0 && deviation < MAX_ALLOWED_FLOW_DEVIATION ) + { + flowOutOfRangeCounter = 0; + } + } - //measuredROPumpPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); TODO what do we do with this? - - - // TODO - check pressure? - - // TODO - check flow? - // Publish RO pump data on interval publishROPumpData(); } /*********************************************************************//** * @brief - * The execROPumpController function executes the RO Pump controller. - * @details - * Inputs: roPumpState - * Outputs: roPumpState + * The execROPumpController function executes the RO pump controller. + * @details Inputs: roPumpState + * @details Outputs: roPumpState * @return none *************************************************************************/ void execROPumpController( void ) @@ -352,26 +379,45 @@ /*********************************************************************//** * @brief - * The isROPumpOn function returns the status of RO pump. - * @details - * Inputs: none - * Outputs: none - * @param: none - * @return isROPumpOn + * The isReverseOsmosisPumpOn function returns the on/off status of RO pump. + * @details Inputs: isROPumpOn + * @details Outputs: none + * @return isROPumpOn the boolean flag that is TRUE if the pump is on and + * FALSE if it is off *************************************************************************/ BOOL isReverseOsmosisPumpOn( void ) { return isROPumpOn; +} + +/*********************************************************************//** + * @brief + * The execROPumpTest function executes the state machine for the RO pump + * self-test. + * @details + * Inputs: TODO FILL UP + * Outputs: TODO FILL UP + * @return the current state of the ROPump self test. + *************************************************************************/ +SELF_TEST_STATUS_T execROPumpTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; + + // TODO - implement self-test(s) + + return result; } /*********************************************************************//** * @brief - * The handleROPumpOffState function handles the ro pump off state \n - * of the ro pump controller state machine. - * @details - * Inputs: roPumpPWMDutyCyclePctSet, isROPumpOn - * Outputs: roPumpPWMDutyCyclePctSet, isROPumpOn - * @return next state + * The handleROPumpOffState function handles the RO pump off state of the + * controller state machine. + * @details Inputs: roPumpControlMode, roPumpControlModeSet, roPumpControlMode, + * roPumpPWMDutyCyclePctSet, roPumpPWMDutyCyclePct, isROPumpOn, + * roPumpOpenLoopTargetDutyCycle + * @details Outputs: roPumpControlModeSet, roPumpPWMDutyCyclePctSet, + * roPumpPWMDutyCyclePct, isROPumpOn + * @return next state of the controller state machine *************************************************************************/ static RO_PUMP_STATE_T handleROPumpOffState( void ) { @@ -387,7 +433,7 @@ setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setROPumpTargetPressure( 120, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setROPumpTargetPressure( 120 ); #ifdef EMC_TEST_BUILD { F32 fanPWM = 0.25; @@ -401,23 +447,24 @@ #endif #endif - // If there is a flow, transition to P controller to get the corresponding pressure of that flow + // If there is a flow, transition to the PI controller to get the corresponding pressure of that flow if ( getTargetROPumpFlowRate() > 0 && roPumpControlMode == PUMP_CONTROL_MODE_CLOSED_LOOP ) { roPumpControlModeSet = roPumpControlMode; // Set initial PWM duty cycle - roPumpPWMDutyCyclePctSet = roPumpPWMDutyCyclePct; - setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); + roPumpDutyCyclePctSet = roPumpPWMDutyCyclePct; + setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); // Reset controller - resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, roPumpPWMDutyCyclePctSet ); + resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, roPumpDutyCyclePctSet ); // Set pump to on isROPumpOn = TRUE; result = RO_PUMP_RAMP_UP_STATE; } - - if ( roPumpOpenLoopTargetPWM > 0 && roPumpControlMode == PUMP_CONTROL_MODE_OPEN_LOOP ) + // If the target duty cycle is greater than zero (minimum is 10%) and the mode has been set to open + // loop, set the duty cycle + if ( roPumpOpenLoopTargetDutyCycle > 0 && roPumpControlMode == PUMP_CONTROL_MODE_OPEN_LOOP ) { - setROPumpControlSignalPWM( roPumpOpenLoopTargetPWM ); + setROPumpControlSignalDutyCycle( roPumpOpenLoopTargetDutyCycle ); isROPumpOn = TRUE; result = RO_PUMP_OPEN_LOOP_STATE; } @@ -427,12 +474,11 @@ /*********************************************************************//** * @brief - * The handleROPumpRampUpState function handles the RO pump ramp up state \n - * of the RO pump controller state machine. - * @details - * Inputs: roControlTimerCounter, roPumpPWMDutyCyclePctSet - * Outputs: roControlTimerCounter, roPumpPWMDutyCyclePctSet - * @return next state + * The handleROPumpRampUpState function handles the RO pump ramp up state of + * the controller state machine. + * @details Inputs: roControlTimerCounter, roPumpPWMDutyCyclePctSet + * @details Outputs: roControlTimerCounter, roPumpPWMDutyCyclePctSet + * @return next state of the controller state machine *************************************************************************/ static RO_PUMP_STATE_T handleROPumpRampUpState( void ) { @@ -442,14 +488,25 @@ if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL ) { F32 targetFlowRate = getTargetROPumpFlowRate(); - F32 actualFlowRate = (F32)getMeasuredROFlowRate(); - - if ( fabs( actualFlowRate - targetFlowRate ) > ROP_FLOW_TARGET_TOLERANCE ) + F32 actualFlowRate = (F32)getMeasuredROFlowRate(); + F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); + + // If the actual pressure is greater than the target pressure or it is within the tolerance of the maximum pressure, move to set + // to target pressure straight. At the beginning the maximum pressure is set in the targetROPumpPressure override variable. + // If the flow rate was reached without reaching to maximum pressure, the pressure that was set to targetROPumpPressure override will + // be reset to the corresponding pressure of the target flow rate. + if ( actualPressure > getTargetROPumpPressure() || ( getTargetROPumpPressure() - actualPressure ) > MAX_PRESSURE_TARGET_TOLERANCE ) + { + result = RO_PUMP_CONTROL_TO_TARGET_STATE; + } + // If the actual flow is still far from target flow, update the duty cycle using the I controller and stay in this state + else if ( fabs( actualFlowRate - targetFlowRate ) > ROP_FLOW_TARGET_TOLERANCE ) { F32 newPWM = runPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, targetFlowRate, actualFlowRate ); - roPumpPWMDutyCyclePctSet = newPWM; - setROPumpControlSignalPWM( newPWM ); + roPumpDutyCyclePctSet = newPWM; + setROPumpControlSignalDutyCycle( newPWM ); } + // Reached to the target flow go to the next state else { result = RO_PUMP_VERIFY_FLOW_STATE; @@ -463,14 +520,13 @@ /*********************************************************************//** * @brief - * The handleROPumpVerifyFlowState function handles the RO pump verify \n + * The handleROPumpVerifyFlowState function handles the RO pump verify * flow state of the RO pump controller state machine. - * @details - * Inputs: flowVerificationCounter, roPumpPWMDutyCyclePctSet, \n - * tgtROPumpPressure, roPumpFlowRateRunningSum, roPumpPressureRunningSum - * Outputs: flowVerificationCounter, roPumpPWMDutyCyclePctSet, \n - * tgtROPumpPressure, roPumpFlowRateRunningSum, roPumpPressureRunningSum - * @return next state + * @details Inputs: flowVerificationCounter, hasTargetFlowBeenReached, + * targetROPumpPressure, roPumpFlowRateRunningSum, roPumpFlowRateRunningSum + * @details Outputs: flowVerificationCounter, hasTargetFlowBeenReached, + * targetROPumpPressure, roPumpFlowRateRunningSum, roPumpFlowRateRunningSum + * @return next state of the controller state machine *************************************************************************/ static RO_PUMP_STATE_T handleROPumpVerifyFlowState( void ) { @@ -495,23 +551,27 @@ F32 targetFlowRate = getTargetROPumpFlowRate(); + // Reached to target flow rate + hasTargetFlowBeenReached = TRUE; + // Calculate the flow rate deviation from the target flow rate F32 flowRateDeviation = ( targetFlowRate - avgFlowRate ) / targetFlowRate; // Use the flow rate deviation to adjust the average calculated pressure. This // pressure is used as the target pressure avgPressure = avgPressure + ( avgPressure * flowRateDeviation ); - + // Save the target pressure targetROPumpPressure.data = avgPressure; } - // Reset the P controller for the flow rate - resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_PWM_DUTY_CYCLE ); + // Reset the I controller for the flow rate as it is no longer needed + resetPIController( I_CONTROLLER_ID_RO_PUMP_RAMP_UP, MIN_RO_PUMP_DUTY_CYCLE ); // Set initial PWM duty cycle - setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); + setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); // Reset controller - resetPIController( PI_CONTROLLER_ID_RO_PUMP, roPumpPWMDutyCyclePctSet ); - flowVerificationCounter = 0; + resetPIController( PI_CONTROLLER_ID_RO_PUMP, roPumpDutyCyclePctSet ); + // Reset all the variables before leaving + flowVerificationCounter = 0; roPumpFlowRateRunningSum = 0; roPumpPressureRunningSum = 0; result = RO_PUMP_CONTROL_TO_TARGET_STATE; @@ -522,32 +582,27 @@ /*********************************************************************//** * @brief - * The handleROPumpControlToTargetState function handles the "control to - * target" state of the RO pump controller state machine. - * @details - * Inputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter - * Outputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter - * @return next state + * The handleROPumpControlToTargetState function handles the control to + * target state of the RO pump controller state machine. + * @details Inputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter, + * roPumpControlModeSet + * @details Outputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter + * @return next state of the controller state machine *************************************************************************/ static RO_PUMP_STATE_T handleROPumpControlToTargetState( void ) { RO_PUMP_STATE_T result = RO_PUMP_CONTROL_TO_TARGET_STATE; - // control at set interval + // Control at set interval if ( ++roControlTimerCounter >= ROP_CONTROL_INTERVAL && roPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) - { + { + // Get the pressure to use it for setting the control F32 actualPressure = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); F32 newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, getTargetROPumpPressure(), actualPressure ); - roPumpPWMDutyCyclePctSet = newPWM; - setROPumpControlSignalPWM( roPumpPWMDutyCyclePctSet ); + roPumpDutyCyclePctSet = newPWM; + setROPumpControlSignalDutyCycle( roPumpDutyCyclePctSet ); -#ifndef EMC_TEST_BUILD - newPWM = runPIController( PI_CONTROLLER_ID_RO_PUMP, tgtPres, actPres ); - roPumpPWMDutyCyclePctSet = newPWM; - setROPumpControlSignalPWM( newPWM ); -#endif - roControlTimerCounter = 0; } @@ -572,12 +627,11 @@ /*********************************************************************//** * @brief - * The handleROPumpOpenLoopState function handles the open loop state \n - * of the RO pump controller - * @details - * Inputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter - * Outputs: roPumpPWMDutyCyclePctSet, roControlTimerCounter - * @return next state + * The handleROPumpOpenLoopState function handles the open loop state of + * the RO pump controller state machine. + * @details Inputs: none + * @details Outputs: none + * @return next state of the controller state machine *************************************************************************/ static RO_PUMP_STATE_T handleROPumpOpenLoopState( void ) { @@ -587,75 +641,73 @@ /*********************************************************************//** * @brief * The setROPumpTargetPressure function sets a new target pressure for the RO pump. - * @details - * Inputs : none - * Outputs : targetROPumpPressure, roPumpPWMDutyCyclePct + * @details Inputs : none + * @details Outputs : targetROPumpPressure, roPumpPWMDutyCyclePct * @param roPressure new target RO pressure - * @param mode new control mode * @return TRUE if new target pressure is set, FALSE if not *************************************************************************/ -static BOOL setROPumpTargetPressure( U32 roPressure, PUMP_CONTROL_MODE_T mode ) +static BOOL setROPumpTargetPressure( U32 roPressure ) { BOOL result = FALSE; - // Verify pressure - if ( roPressure >= 10 && roPressure <= 50 ) + // Verify pressure is in the allowed range + if ( roPressure >= MIN_ALLOWED_PRESSURE_PSI && roPressure <= MAX_ALLOWED_PRESSURE_PSI ) { targetROPumpPressure.data = roPressure; - roPumpControlMode = mode; + // Set the control mode to open loop + roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; // set PWM duty cycle target to an estimated initial target based on target pressure - then we'll control to pressure going forward #ifdef EMC_TEST_BUILD roPumpPWMDutyCyclePct = 1.0; #else - roPumpPWMDutyCyclePct = ROP_PSI_TO_PWM_DC( roPressure ); + roPumpPWMDutyCyclePct = ROP_PSI_TO_PWM_DC( targetROPumpPressure.data ); #endif result = TRUE; } - else // requested pressure out of range + // Invalid pressure was selected + else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, 0, roPressure ) // TODO - replace 1st param with s/w fault enum + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVAID_PRESSURE_SELECTED, roPressure ) } return result; } /*********************************************************************//** * @brief - * The setROPumpControlSignalPWM function sets the PWM duty cycle for the - * RO pump to a given %. - * @details - * Inputs: none - * Outputs: PWM duty cycle zeroed - * @param: newPWM : new duty cycle % to apply to PWM + * The setROPumpControlSignalDutyCycle function sets the duty cycle for the + * RO pump to a given duty cycle. + * @details Inputs: none + * @details Outputs: none + * @param dutyCycle which is the duty cycle * @return none *************************************************************************/ -static void setROPumpControlSignalPWM( F32 newPWM ) +static void setROPumpControlSignalDutyCycle( F32 dutyCycle ) { - etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( newPWM * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); + etpwmSetCmpB( etpwmREG2, (U32)( (S32)( ( dutyCycle * (F32)(etpwmREG2->TBPRD) ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ) ); } /*********************************************************************//** * @brief - * The stopROPump function sets the RO pump PWM to zero. - * @details - * Inputs: none - * Outputs: PWM duty cycle zeroed + * The stopROPump function sets the RO pump duty cycle to zero. + * @details Inputs: isROPumpOn, roPumpPWMDutyCyclePctSet + * @details Outputs: isROPumpOn, roPumpPWMDutyCyclePctSet * @return none *************************************************************************/ static void stopROPump( void ) { isROPumpOn = FALSE; - roPumpPWMDutyCyclePctSet = 0.0; + roPumpDutyCyclePctSet = 0.0; etpwmSetCmpB( etpwmREG2, 0 ); } /*********************************************************************//** * @brief - * The getPublishROPumpDataInterval function gets the RO pump data publish interval. - * @details - * Inputs: roPumpDataPublishInterval - * Outputs: none + * The getPublishROPumpDataInterval function gets the RO pump data publish + * interval. + * @details Inputs: roPumpDataPublishInterval + * @details Outputs: roPumpDataPublishInterval * @return the current RO pump data publication interval (in ms). *************************************************************************/ static U32 getPublishROPumpDataInterval( void ) @@ -672,12 +724,11 @@ /*********************************************************************//** * @brief - * The getTargetROPumpFlowRate function gets the current target RO pump \n - * flow rate - * @details - * Inputs: targetROPumpFlowRate - * Outputs: targetROPumpFlowRate - * @return the current target RO flow rate (in LPM). + * The getTargetROPumpFlowRate function gets the current target RO pump + * flow rate. + * @details Inputs: targetROPumpFlowRate + * @details Outputs: targetROPumpFlowRate + * @return the current target RO flow rate (in L/min). *************************************************************************/ F32 getTargetROPumpFlowRate( void ) { @@ -694,10 +745,9 @@ /*********************************************************************//** * @brief * The getMeasuredROFlowRate function gets the measured RO pump flow rate. - * @details - * Inputs: measuredROFlowRateLPM - * Outputs: none - * @return the current RO pump flow rate (in LPM). + * @details Inputs: measuredROFlowRateLPM + * @details Outputs: measuredROFlowRateLPM + * @return the current RO pump flow rate (in L/min). *************************************************************************/ F32 getMeasuredROFlowRate( void ) { @@ -734,9 +784,8 @@ /*********************************************************************//** * @brief * The publishROPumpData function publishes RO pump data at the set interval. - * @details - * Inputs: target pressure, measured pressure, measured RO pump speed. - * Outputs: RO pump data is published to CAN bus. + * @details Inputs: roPumpDataPublicationTimerCounter + * @details Outputs: roPumpDataPublicationTimerCounter * @return none *************************************************************************/ static void publishROPumpData( void ) @@ -747,33 +796,15 @@ RO_PUMP_DATA_T pumpData; pumpData.roPumpTgtPressure = getTargetROPumpPressure(); - pumpData.measROFlowRate = getMeasuredROFlowRate(); - pumpData.roPumpPWM = roPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; - pumpData.roPumpState = (U32)roPumpState; + pumpData.measROFlowRate = getMeasuredROFlowRate(); + pumpData.roPumpDutyCycle = roPumpDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; + pumpData.roPumpState = (U32)roPumpState; broadcastROPumpData( &pumpData ); roPumpDataPublicationTimerCounter = 0; } -} +} -/*********************************************************************//** - * @brief - * The execROPumpTest function executes the state machine for the ROPump self-test. - * @details - * Inputs: none - * Outputs: none - * @return the current state of the ROPump self test. - *************************************************************************/ -SELF_TEST_STATUS_T execROPumpTest( void ) -{ - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; - - // TODO - implement self-test(s) - - return result; -} - - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -783,9 +814,8 @@ * @brief * The testSetROPumpDataPublishIntervalOverride function overrides the * RO pump data publish interval. - * @details - * Inputs: none - * Outputs: roPumpDataPublishInterval + * @details Inputs: roPumpDataPublishInterval + * @details Outputs: roPumpDataPublishInterval * @param: value : override RO pump data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ @@ -796,22 +826,21 @@ if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; - + roPumpDataPublishInterval.ovData = intvl; + roPumpDataPublishInterval.override = OVERRIDE_KEY; + result = TRUE; - roPumpDataPublishInterval.ovData = intvl; - roPumpDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief - * The testResetROPumpDataPublishIntervalOverride function resets the override - * of the RO pump data publish interval. - * @details - * Inputs: none - * Outputs: roPumpDataPublishInterval + * The testResetROPumpDataPublishIntervalOverride function resets the + * override of the RO pump data publish interval. + * @details Inputs: roPumpDataPublishInterval + * @details Outputs: roPumpDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetROPumpDataPublishIntervalOverride( void ) @@ -820,22 +849,22 @@ if ( TRUE == isTestingActivated() ) { - result = TRUE; roPumpDataPublishInterval.override = OVERRIDE_RESET; - roPumpDataPublishInterval.ovData = roPumpDataPublishInterval.ovInitData; + roPumpDataPublishInterval.ovData = roPumpDataPublishInterval.ovInitData; + + result = TRUE; } return result; } /*********************************************************************//** * @brief - * The testSetTargetROPumpFlowRateOverride function overrides the target \n - * RO flow rate. \n - * @details - * Inputs: targetROPumpFlowRate - * Outputs: targetROPumpPressure - * @param: value : override target RO flow rate (in LPM) + * The testSetTargetROPumpFlowRateOverride function overrides the target + * flow rate. + * @details Inputs: targetROPumpFlowRate + * @details Outputs: targetROPumpFlowRate + * @param: value which is override target RO flow rate (in L/min) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTargetROPumpFlowRateOverride( F32 value ) @@ -844,22 +873,21 @@ if ( TRUE == isTestingActivated() ) { - targetROPumpFlowRate.ovInitData = targetROPumpFlowRate.data; // backup current target pressure - targetROPumpFlowRate.ovData = value; - targetROPumpFlowRate.override = OVERRIDE_KEY; - //result = setROPumpTargetFlowRate( value ); + targetROPumpFlowRate.ovInitData = targetROPumpFlowRate.data; + targetROPumpFlowRate.ovData = value; + targetROPumpFlowRate.override = OVERRIDE_KEY; + //result = setROPumpTargetFlowRate( value ); TODO what should be pressure here? } return result; } /*********************************************************************//** * @brief - * The testResetTargetROPumpPressureOverride function resets the override of the - * target RO pressure. - * @details - * Inputs : none - * Outputs : targetROPumpPressure + * The testResetTargetROPumpFlowRateOverride function resets the override + * of the target RO flow rate. + * @details Inputs: targetROPumpFlowRate + * @details Outputs: targetROPumpFlowRate * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetTargetROPumpFlowRateOverride( void ) @@ -868,11 +896,13 @@ if ( TRUE == isTestingActivated() ) { - targetROPumpFlowRate.data = targetROPumpFlowRate.ovInitData; // restore pre-override target pressure - targetROPumpFlowRate.override = OVERRIDE_RESET; + // Reset the override + targetROPumpFlowRate.data = targetROPumpFlowRate.ovInitData; + targetROPumpFlowRate.override = OVERRIDE_RESET; targetROPumpFlowRate.ovInitData = 0; - targetROPumpFlowRate.ovData = 0; - //result = setROPumpTargetFlowRate( targetROPumpFlowRate.data ); + targetROPumpFlowRate.ovData = 0; + // Set the flow rate back to its original as well as the pressure + result = setROPumpTargetFlowRate( targetROPumpFlowRate.data, getTargetROPumpPressure() ); } return result; @@ -882,10 +912,9 @@ * @brief * The testSetTargetROPumpPressureOverride function overrides the target * RO pressure. - * @details - * Inputs : none - * Outputs : targetROPumpPressure - * @param value override target RO pressure (in PSI) + * @details Inputs: targetROPumpPressure + * @details Outputs: targetROPumpPressure + * @param value override target RO pressure (in psi) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTargetROPumpPressureOverride( U32 value ) @@ -894,22 +923,21 @@ if ( TRUE == isTestingActivated() ) { - targetROPumpPressure.ovInitData = targetROPumpPressure.data; // backup current target pressure - targetROPumpPressure.ovData = value; - targetROPumpPressure.override = OVERRIDE_KEY; - result = setROPumpTargetPressure( value, roPumpControlMode ); + targetROPumpPressure.ovInitData = targetROPumpPressure.data; + targetROPumpPressure.ovData = value; + targetROPumpPressure.override = OVERRIDE_KEY; + result = setROPumpTargetPressure( value ); } return result; } /*********************************************************************//** * @brief - * The testResetTargetROPumpPressureOverride function resets the override of the - * target RO pressure. - * @details - * Inputs : none - * Outputs : targetROPumpPressure + * The testResetTargetROPumpPressureOverride function resets the override + * of the target RO pressure. + * @details Inputs: targetROPumpPressure + * @details Outputs: targetROPumpPressure * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetTargetROPumpPressureOverride( void ) @@ -918,11 +946,11 @@ if ( TRUE == isTestingActivated() ) { - targetROPumpPressure.data = targetROPumpPressure.ovInitData; // restore pre-override target pressure - targetROPumpPressure.override = OVERRIDE_RESET; + targetROPumpPressure.data = targetROPumpPressure.ovInitData; + targetROPumpPressure.override = OVERRIDE_RESET; targetROPumpPressure.ovInitData = 0; - targetROPumpPressure.ovData = 0; - result = setROPumpTargetPressure( targetROPumpPressure.data, roPumpControlMode ); + targetROPumpPressure.ovData = 0; + result = setROPumpTargetPressure( targetROPumpPressure.data ); } return result; @@ -932,10 +960,9 @@ * @brief * The testSetMeasuredROFlowRateOverride function overrides the measured * RO flow rate. - * @details - * Inputs: none - * Outputs: measuredROFlowRateLPM - * @param: value : override measured RO pump motor speed (in LPM) + * @details Inputs: measuredROFlowRateLPM + * @details Outputs: measuredROFlowRateLPM + * @param: value : override measured RO pump motor speed (in L/min) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetMeasuredROFlowRateOverride( F32 value ) @@ -944,37 +971,89 @@ if ( TRUE == isTestingActivated() ) { + measuredROFlowRateLPM.ovInitData = measuredROFlowRateLPM.data; + measuredROFlowRateLPM.ovData = value; + measuredROFlowRateLPM.override = OVERRIDE_KEY; + result = TRUE; - measuredROFlowRateLPM.ovData = value; - measuredROFlowRateLPM.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief - * The testResetMeasuredROFlowRateOverride function resets the override of the - * measured RO flow rate. - * @details - * Inputs: none - * Outputs: measuredROFlowRateLPM - * @param: none - + * The testResetMeasuredROFlowRateOverride function resets the override + * of the measured RO flow rate. + * @details Inputs: measuredROFlowRateLPM + * @details Outputs: measuredROFlowRateLPM * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testResetMeasuredROFlowRateOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) - { + { + measuredROFlowRateLPM.data = measuredROFlowRateLPM.ovInitData; + measuredROFlowRateLPM.override = OVERRIDE_RESET; + measuredROFlowRateLPM.ovInitData = 0.0; + measuredROFlowRateLPM.ovData = 0.0; + result = TRUE; - measuredROFlowRateLPM.override = OVERRIDE_RESET; - measuredROFlowRateLPM.ovData = measuredROFlowRateLPM.ovInitData; } return result; -} +} +/*********************************************************************//** + * @brief + * The testSetTargetDutyCycleOverride function overrides the target duty + * cycle of the RO pump. + * @details Inputs: none + * @details Outputs: none + * @param value which is the duty cycle to be set + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetTargetDutyCycleOverride( F32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + // Check if duty cycle is within ranges + if ( value >= MIN_RO_PUMP_DUTY_CYCLE && value <= MAX_RO_PUMP_DUTY_CYCLE ) + { + setROPumpTargetDutyCycle( value ); + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetTargetDutyCyceOverride function resets and turns off the + * RO pump that was running at a certain duty cycle. + * @details Inputs: none + * @details Outputs: none + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetTargetDutyCyceOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + // Reset of the duty cycle override means stop the pump and + // reset all its variables + signalROPumpHardStop(); + + result = TRUE; + } + + return result; +} + /**@}*/ Index: firmware/App/Controllers/ROPump.h =================================================================== diff -u -r1f500f8e6159a3fbab85ea68389e918a6df66400 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 1f500f8e6159a3fbab85ea68389e918a6df66400) +++ firmware/App/Controllers/ROPump.h (.../ROPump.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -37,7 +37,7 @@ { F32 roPumpTgtPressure; ///< RO pump target pressure F32 measROFlowRate; ///< RO flow rate measurement - F32 roPumpPWM; ///< RO pump pwm + F32 roPumpDutyCycle; ///< RO pump pwm U32 roPumpState; ///< RO pump current state } RO_PUMP_DATA_T; @@ -66,12 +66,15 @@ BOOL testSetTargetROPumpFlowRateOverride( F32 value ); BOOL testResetTargetROPumpFlowRateOverride( void ); +BOOL testSetMeasuredROFlowRateOverride( F32 value ); +BOOL testResetMeasuredROFlowRateOverride( void ); + BOOL testSetTargetROPumpPressureOverride( U32 value ); -BOOL testResetTargetROPumpPressureOverride( void ); +BOOL testResetTargetROPumpPressureOverride( void ); + +BOOL testSetTargetDutyCycleOverride( F32 value ); +BOOL testResetTargetDutyCyceOverride( void ); -BOOL testSetMeasuredROFlowRateOverride( F32 value ); -BOOL testResetMeasuredROFlowRateOverride( void ); - /**@}*/ #endif Index: firmware/App/Controllers/Thermistors.c =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -1,5 +1,5 @@ -#include +#include // For temperature calculations #include "Thermistors.h" #include "FPGA.h" @@ -67,7 +67,7 @@ static const F32 onBoardThermistorVoltageConvCoeff = ONBOARD_THERMISTOR_SOURCE_VOLTAGE / TWELVE_BIT_RESOLUTION; ///< On board thermistor ADC to voltage conversion coefficient static const F32 onBoardThermistorBetaValueInv = 1 / ONBOARD_THERMISTOR_BETA_VALUE; ///< On board thermistor beta value inverse -static const F32 onBoardThermistorRefTempInv = 1 / ONBOARD_THERMISTOR_REFERENCE_TEMPERATURE; ///< On board thermistor reference temONBOARD_THERMISTOR_REFERENCE_TEMPERATUREperature inverse +static const F32 onBoardThermistorRefTempInv = 1 / ONBOARD_THERMISTOR_REFERENCE_TEMPERATURE; ///< On board thermistor reference inverse // ********** private function prototypes ********** @@ -223,8 +223,8 @@ // Get all the raw readings in ADC thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getIntADCReading( INT_ADC_BOARD_THERMISTOR ); thermistorsStatus[ TEMPSENSOR_FPGA_SENSOR ].rawADCRead = getFPGABoardTemp(); - thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A1 ].rawADCRead = getFPGALoadCellsA1B1Temp(); - thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A2 ].rawADCRead = getFPGALoadCellsA2B2Temp(); + thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A1_B1 ].rawADCRead = getFPGALoadCellsA1B1Temp(); + thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A2_B2 ].rawADCRead = getFPGALoadCellsA2B2Temp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_THDO_RTD ].rawADCRead = getFPGATHDoInternalTemp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_TDI_RTD ].rawADCRead = getFPGATDiInternalTemp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_CONDUCTIVITY ].rawADCRead = getFPGAConductivitySnsrInternalTemp(); @@ -294,8 +294,8 @@ // Get all the raw readings in ADC thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getIntADCReading( INT_ADC_BOARD_THERMISTOR ); thermistorsStatus[ TEMPSENSOR_FPGA_SENSOR ].rawADCRead = getFPGABoardTemp(); - thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A1 ].rawADCRead = getFPGALoadCellsA1B1Temp(); - thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A2 ].rawADCRead = getFPGALoadCellsA2B2Temp(); + thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A1_B1 ].rawADCRead = getFPGALoadCellsA1B1Temp(); + thermistorsStatus[ TEMPSENSOR_LOAD_CELL_A2_B2 ].rawADCRead = getFPGALoadCellsA2B2Temp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_THDO_RTD ].rawADCRead = getFPGATHDoInternalTemp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_TDI_RTD ].rawADCRead = getFPGATDiInternalTemp(); thermistorsStatus[ TEMPSENSOR_INTERNAL_CONDUCTIVITY ].rawADCRead = getFPGAConductivitySnsrInternalTemp(); @@ -387,8 +387,8 @@ break; // All these sensors have the same conversion procedure - case TEMPSENSOR_LOAD_CELL_A1: - case TEMPSENSOR_LOAD_CELL_A2: + case TEMPSENSOR_LOAD_CELL_A1_B1: + case TEMPSENSOR_LOAD_CELL_A2_B2: case TEMPSENSOR_INTERNAL_THDO_RTD: case TEMPSENSOR_INTERNAL_TDI_RTD: case TEMPSENSOR_INTERNAL_CONDUCTIVITY: @@ -477,8 +477,8 @@ // Get all the sensors/thermistors temperature values for publication sensorsData.onboardThermistor = getThermistorTemperatureValue( THERMISTOR_ONBOARD_NTC ); sensorsData.fpgaBoardTempSensor = getThermistorTemperatureValue( TEMPSENSOR_FPGA_SENSOR ); - sensorsData.loadCellA1TempSensor = getThermistorTemperatureValue( TEMPSENSOR_LOAD_CELL_A1 ); - sensorsData.loadCellA2TempSensor = getThermistorTemperatureValue( TEMPSENSOR_LOAD_CELL_A2 ); + sensorsData.loadCellA1TempSensor = getThermistorTemperatureValue( TEMPSENSOR_LOAD_CELL_A1_B1 ); + sensorsData.loadCellA2TempSensor = getThermistorTemperatureValue( TEMPSENSOR_LOAD_CELL_A2_B2 ); sensorsData.rtdInternalTempSensor = getThermistorTemperatureValue( TEMPSENSOR_INTERNAL_THDO_RTD ); sensorsData.rtdTDiInternalTempSensor = getThermistorTemperatureValue( TEMPSENSOR_INTERNAL_TDI_RTD ); sensorsData.conductivityTempSensor = getThermistorTemperatureValue( TEMPSENSOR_INTERNAL_CONDUCTIVITY ); Index: firmware/App/Controllers/Thermistors.h =================================================================== diff -u -r1f500f8e6159a3fbab85ea68389e918a6df66400 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/Thermistors.h (.../Thermistors.h) (revision 1f500f8e6159a3fbab85ea68389e918a6df66400) +++ firmware/App/Controllers/Thermistors.h (.../Thermistors.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -21,8 +21,8 @@ { THERMISTOR_ONBOARD_NTC = 0, ///< Onboard thermistor TEMPSENSOR_FPGA_SENSOR, ///< FPGA board temperature sensor - TEMPSENSOR_LOAD_CELL_A1, ///< Load cell A1 temperature sensor - TEMPSENSOR_LOAD_CELL_A2, ///< Load cell A2 temperature sensor + TEMPSENSOR_LOAD_CELL_A1_B1, ///< Load cell A1/B1 temperature sensor + TEMPSENSOR_LOAD_CELL_A2_B2, ///< Load cell A2/B2 temperature sensor TEMPSENSOR_INTERNAL_THDO_RTD, ///< THDo RTD internal temperature sensor TEMPSENSOR_INTERNAL_TDI_RTD, ///< TDi RTD internal temperature sensor TEMPSENSOR_INTERNAL_CONDUCTIVITY, ///< Conductivity sensor temperature sensor Index: firmware/App/Controllers/UVReactors.c =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -14,14 +14,14 @@ // ********** private definitions ********** -#define INLET_UV_REACTOR_ENABLE_PIN 0 ///< Inlet UV reactor GPIO pin number (enable pin) -#define OUTLET_UV_REACTOR_ENABLE_PIN 1 ///< Outlet UV reactor GPIO pin number (enable Pin) -#define INLET_UV_REACTOR_INDICATION_PIN 26 ///< Inlet UV reactor N2HET1 pin number (health check) -#define OUTLET_UV_REACTOR_INDICATION_PIN 11 ///< Outlet UV reactor N2HET1 pin number (health check) -#define UV_REACTORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors data publication time interval -/// Self test wait time after enabling the reactors and before checking for their health in ms +#define INLET_UV_REACTOR_ENABLE_PIN 0 ///< Inlet UV reactor GPIO pin number (enable pin). +#define OUTLET_UV_REACTOR_ENABLE_PIN 1 ///< Outlet UV reactor GPIO pin number (enable Pin). +#define INLET_UV_REACTOR_INDICATION_PIN 26 ///< Inlet UV reactor N2HET1 pin number (health check). +#define OUTLET_UV_REACTOR_INDICATION_PIN 11 ///< Outlet UV reactor N2HET1 pin number (health check). +#define UV_REACTORS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors data publication time interval. +/// Self test wait time after enabling the reactors and before checking for their health in ms. #define SELF_TEST_DELAY_TIME 1000 -#define MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors max counter to be unhealthy +#define MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< UV reactors max counter to be unhealthy. /// UV reactors self test states typedef enum self_tests @@ -49,7 +49,7 @@ U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1 U32 reactorUnhealthyCounter; ///< UV reactor counter of the number of times it is unhealthy in a row - BOOL reactorCurrentHealthStatus; ///< UV reactor current health status + OVERRIDE_U32_T healthStatus; ///< UV reactor current health status } UV_REACTOR_STATUS_T; // ********** private data ********** @@ -61,8 +61,6 @@ static OVERRIDE_U32_T uvReactorsDataPublishInterval = { UV_REACTORS_DATA_PUB_INTERVAL, UV_REACTORS_DATA_PUB_INTERVAL, 0, 0 }; ///< UV reactors data publish interval -static OVERRIDE_U32_T uvReactorsStateOverride[ NUM_OF_UV_REACTORS ]; ///< UV reactors state override TODO Remove - static U32 dataPublishCounter = 0; ///< UV reactors data publish counter static U32 selfTestElapsedTime = 0; ///< UV reactors self test elapsed time @@ -75,7 +73,7 @@ static UV_REACTOR_STATE_T handleUVReactorStateOn( UV_REACTORS_T reactor ); // Support functions -static BOOL isReactorHealthy( UV_REACTORS_T reactor ); +static U32 isReactorHealthy( UV_REACTORS_T reactor ); static void setReactorEnableStatus( UV_REACTORS_T reactor, PIN_SIGNAL_STATE_T state ); static void publishUVReactorsData( void ); static U32 getPublishUVReactorsDataInterval( void ); @@ -190,7 +188,27 @@ *************************************************************************/ BOOL getUVReactorHealth( UV_REACTORS_T reactor ) { - return reactorsStatus[ reactor ].reactorCurrentHealthStatus; + BOOL health; + + // Check if the reactor selected is in range + if ( reactor < NUM_OF_UV_REACTORS ) + { + // Check if the health is in override or not + if ( reactorsStatus[ reactor ].healthStatus.override == OVERRIDE_KEY ) + { + health = reactorsStatus[ reactor ].healthStatus.ovData; + } + else + { + health = reactorsStatus[ reactor ].healthStatus.data; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) + } + + return health; } /*********************************************************************//** @@ -216,7 +234,7 @@ } else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACOTRS_INVALID_REACTOR_SELECTD, reactor ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) } return result; @@ -236,15 +254,12 @@ // Check if the called reactor is in range if ( reactor < NUM_OF_UV_REACTORS ) { - if ( TRUE == reactorsStatus[ reactor ].hasTurnOnBeenRequested ) - { - reactorsStatus[ reactor ].hasTurnOnBeenRequested = FALSE; - result = TRUE; - } + reactorsStatus[ reactor ].hasTurnOnBeenRequested = FALSE; + result = TRUE; } else { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACOTRS_INVALID_REACTOR_SELECTD, reactor ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, reactor ) } return result; @@ -284,11 +299,11 @@ if ( didTimeout( selfTestElapsedTime, SELF_TEST_DELAY_TIME ) ) { // Get the health status of the reactors - BOOL isInletHealthy = isReactorHealthy( INLET_UV_REACTOR ); - BOOL isOutletHealty = isReactorHealthy( OUTLET_UV_REACTOR ); + BOOL isInletHealthy = (BOOL)isReactorHealthy( INLET_UV_REACTOR ); + BOOL isOutletHealty = (BOOL)isReactorHealthy( OUTLET_UV_REACTOR ); // Check if both of them are healthy and if not, raise an alarm - if ( isInletHealthy && isOutletHealty ) + if ( TRUE == isInletHealthy && TRUE == isOutletHealty ) { uvReactosSelfTestResult = SELF_TEST_STATUS_PASSED; } @@ -334,8 +349,6 @@ { setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); - // Update the pin signal state - reactorsStatus[ reactor ].pinSignalState = PIN_SIGNAL_HIGH; state = UV_REACTOR_STATE_ON; } @@ -353,14 +366,14 @@ static UV_REACTOR_STATE_T handleUVReactorStateOn( UV_REACTORS_T reactor ) { UV_REACTOR_STATE_T state = UV_REACTOR_STATE_ON; - BOOL health = isReactorHealthy( reactor ); - reactorsStatus[ reactor ].reactorCurrentHealthStatus = health; + reactorsStatus[ reactor ].healthStatus.data = isReactorHealthy( reactor ); + // Check if the reactor is healthy - if ( FALSE == health && ++reactorsStatus[ reactor ].reactorUnhealthyCounter > MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ) + if ( FALSE == getUVReactorHealth( reactor ) && ++reactorsStatus[ reactor ].reactorUnhealthyCounter > MAX_ALLOWED_UNHEALTHY_REACTOR_COUNTER ) { // The reactor has been unhealthy for a certain amount of time - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_UV_REACTOR_NOT_HEALTHY , reactor ); + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_UV_REACTOR_NOT_HEALTHY, reactor ); } else { @@ -373,8 +386,6 @@ { setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); - // Update the pin signal state - reactorsStatus[ reactor ].pinSignalState = PIN_SIGNAL_LOW; state = UV_REACTOR_STATE_OFF; } @@ -395,6 +406,9 @@ { // Set the GIO pin to enable or disable gioSetBit( gioPORTA, reactorsStatus[ reactor ].reactorEnablePin, state ); + + // Update the pin signal state + reactorsStatus[ reactor ].pinSignalState = state; } /*********************************************************************//** @@ -405,11 +419,9 @@ * @param reactor to check its health * @return returns TRUE if the reactor is healthy otherwise a FALSE *************************************************************************/ -static BOOL isReactorHealthy( UV_REACTORS_T reactor ) +static U32 isReactorHealthy( UV_REACTORS_T reactor ) { - U32 status = gioGetBit( hetPORT1, reactorsStatus[ reactor ].reactorHealthStatusPin ); - - return (BOOL)status; + return gioGetBit( hetPORT1, reactorsStatus[ reactor ].reactorHealthStatusPin ); } /*********************************************************************//** @@ -509,46 +521,37 @@ /*********************************************************************//** * @brief - * The testSetUVReactorsStateOverride function overrides the UV reactors - * state - * @details Inputs: uvReactorsStateOverride, reactorsStatus - * @details Outputs: uvReactorsStateOverride - * @param reactor that its state will be overridden - * @param signal which is high for turn on and low for turn off + * The testSetUVReactorHealthOverride function overrides the UV reactors + * health + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor that its health will be overridden + * @param health which is high for healthy on and low for not healthy * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testSetUVReactorHealthOverride( U32 reactor, PIN_SIGNAL_STATE_T signal ) +BOOL testSetUVReactorHealthOverride( U32 reactor, BOOL health ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() && (UV_REACTORS_T)reactor < NUM_OF_UV_REACTORS ) { - // Get the current position of the valve as the initial position - uvReactorsStateOverride[ reactor ].ovInitData = reactorsStatus[ reactor ].pinSignalState; - uvReactorsStateOverride[ reactor ].ovData = signal; - uvReactorsStateOverride[ reactor ].override = OVERRIDE_KEY; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovInitData = reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.data; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.override = OVERRIDE_KEY; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovData = (U32)health; - // If the signal is high, turn on the reactor - if ( signal == PIN_SIGNAL_HIGH ) - { - result = turnOnUVReactor( (UV_REACTORS_T)reactor ); - } - else - { - result = turnOffUVReactor( (UV_REACTORS_T)reactor ); - } + result = TRUE; } return result; } /*********************************************************************//** * @brief - * The testResetUVReactorsStateOverride function resets the override - * of the UV reactors state - * @details Inputs: uvReactorsStateOverride - * @details Outputs: uvReactorsStateOverride - * @param reactor that its state will be reset + * The testResetUVReactorHealthOverride function resets the override + * of the UV reactors health + * @details Inputs: reactorsStatus + * @details Outputs: reactorsStatus + * @param reactor that its health will be reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetUVReactorHealthOverride( U32 reactor ) @@ -557,18 +560,8 @@ if ( TRUE == isTestingActivated() && (UV_REACTORS_T)reactor < NUM_OF_UV_REACTORS ) { - uvReactorsStateOverride[ reactor ].override = OVERRIDE_RESET; - uvReactorsStateOverride[ reactor ].ovData = uvReactorsStateOverride[ reactor ].ovInitData; - - if ( uvReactorsStateOverride[ reactor ].ovData == PIN_SIGNAL_HIGH ) - { - result = turnOnUVReactor( (UV_REACTORS_T)reactor ); - } - else - { - result = turnOffUVReactor( (UV_REACTORS_T)reactor ); - } - + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.override = OVERRIDE_RESET; + reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovData = reactorsStatus[ (UV_REACTORS_T)reactor ].healthStatus.ovInitData; } return result; Index: firmware/App/Controllers/UVReactors.h =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Controllers/UVReactors.h (.../UVReactors.h) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Controllers/UVReactors.h (.../UVReactors.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -46,7 +46,7 @@ BOOL testSetReactorsDataPublishInterval( U32 value ); BOOL testResetReactorsDataPublishInterval( void ); -BOOL testSetUVReactorHealthOverride( U32 reactor, PIN_SIGNAL_STATE_T signal ); +BOOL testSetUVReactorHealthOverride( U32 reactor, BOOL health ); BOOL testResetUVReactorHealthOverride( U32 reactor ); /**@}*/ Index: firmware/App/DGCommon.h =================================================================== diff -u -r8f95cb0d5ca434bdaf3e157e399e017d12212d3d -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/DGCommon.h (.../DGCommon.h) (revision 8f95cb0d5ca434bdaf3e157e399e017d12212d3d) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -36,7 +36,7 @@ // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing // #define DISABLE_HEATERS_AND_TEMPS 1 - #define EMC_TEST_BUILD 1 +// #define EMC_TEST_BUILD 1 // #define DISABLE_ACCELS 1 #define SKIP_POST 1 Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r45263215b372cd579e8e16bb8073c287c726c55d -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 45263215b372cd579e8e16bb8073c287c726c55d) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -958,8 +958,13 @@ { if ( ++heatDisinfectPublishCounter >= getPublishHeatDisinfectDataInterval() ) { - F32 elapsedtime = calcTimeSince( heatDisinfectStartTime ) / MINUTE_TO_MS_CONVERSION; - broadcastHeatDisinfectData( (U32)heatDisinfectInternalState, elapsedtime, heatDisinfectCurrentCycle ); + DG_HEAT_DISINFECT_DATA_T data; + + data.currentCycle = heatDisinfectCurrentCycle; + data.elapsedTimeMins = calcTimeSince( heatDisinfectStartTime ) / MINUTE_TO_MS_CONVERSION;; + data.internalState = (U32)heatDisinfectInternalState; + + broadcastHeatDisinfectData( &data ); heatDisinfectPublishCounter = 0; } } Index: firmware/App/Modes/ModeHeatDisinfect.h =================================================================== diff -u -raa36ab1ed13d099286cedcbd066f7dce11146d13 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision aa36ab1ed13d099286cedcbd066f7dce11146d13) +++ firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -33,6 +33,16 @@ // ********** public definitions ********** +#pragma pack(push,1) +/// Heat disinfect data +typedef struct +{ + U32 internalState; ///< Internal state of heat disinfect state machine + F32 elapsedTimeMins; ///< Heat disinfect elapsed time in minutes + U32 currentCycle; ///< Current cycle of the heat disinfect +} DG_HEAT_DISINFECT_DATA_T; +#pragma pack(pop) + // ********** public function prototypes ********** void initHeatDisinfectMode( void ); // initialize this module Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -155,7 +155,8 @@ SW_FAULT_ID_RO_PUMP_INVALID_EXEC_STATE, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, SW_FAULT_ID_DRAIN_PUMP_INVALID_EXEC_STATE, // 65 - SW_FAULT_ID_UV_REACOTRS_INVALID_REACTOR_SELECTD, + SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD, + SW_FAULT_ID_RO_PUMP_INVAID_PRESSURE_SELECTED, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r1f500f8e6159a3fbab85ea68389e918a6df66400 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 1f500f8e6159a3fbab85ea68389e918a6df66400) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -158,6 +158,17 @@ U16 fpgaValveStates; ///< Reg 376. Valves states U16 fpgaFan1Pulse; ///< Reg 378. Fan 1 pulse U16 fpgaFan2Pulse; ///< Reg 380. Fan 2 pulse + + U08 fpgaEmstatOutByte; ///< Reg 382. Emstat output FIFO - data from the Emstat device + U08 fpgaEmstatRxErrorCount; ///< Reg 383. Number of receive errors since power-up + U16 fpgaEmstatTxFifoCount; ///< Reg 384. Number of bytes in the Emstat Tx FIFO buffer + U16 fpgaEmstatRxFifoCount; ///< Reg 386. Number of bytes in the Emstat Rx FIFO buffer + U16 fpgaCP1HallSense; ///< Reg 388. Concentrate pump CP1 hall sensor pulse width + U16 fpgaCP2HallSense; ///< Reg 390. Concentrate pump CP2 hall sensor pulse width + + U08 fpgaGPIOReg; ///< Reg 392. FGPA GPIO register + U08 fpgaDummyByte2Addr; ///< Reg 393. Dummy byte address to maintain an even addressing scheme + U16 fpgaADCTemp; ///< Reg 394. Internal FPGA die temperature ADC } DG_FPGA_SENSORS_T; typedef struct @@ -1579,8 +1590,7 @@ *************************************************************************/ U32 getFPGABoardTemp( void ) { - // TODO add the FPGA board temperature sensor register - return 0; + return fpgaSensorReadings.fpgaADCTemp; } /*********************************************************************//** Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r1f500f8e6159a3fbab85ea68389e918a6df66400 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 1f500f8e6159a3fbab85ea68389e918a6df66400) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -107,7 +107,7 @@ U16 getFPGAOutletFan2TogglePeriod( void ); U16 getFPGAOutletFan3TogglePeriod( void ); -U32 getFPGABoardTemp( void ); //TODO add the FPGA board temperature sensor +U32 getFPGABoardTemp( void ); U32 getFPGALoadCellsA1B1Temp( void ); U32 getFPGALoadCellsA2B2Temp( void ); U32 getFPGATHDoInternalTemp( void ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -1182,12 +1182,29 @@ break; case MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE: - handleUVReactorsDataPunlishIntervalOverride( message ); + handleUVReactorsDataPublishIntervalOverride( message ); break; case MSG_ID_DG_START_STOP_OUTLET_UV_REACTOR: + handleStartStopOutletUVReactor( message ); break; + case MSG_ID_DG_UV_REACTORS_HEALTH_OVERRIDE: + handleUVReactorsHealthOverride( message ); + break; + + case MSG_ID_DG_THERMISTORS_DATA_PUBLISH_INTERVAL_OVERRIDE: + handleThermistorsDataPublishIntervalOverride( message ); + break; + + case MSG_ID_DG_THERMISTORS_VALUE_OVERRIDE: + handleThermisotrsValueOverride( message ); + break; + + case MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE: + handleROPumpDutyCycleOverride( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemComm.h =================================================================== diff -u -rab304e2ca6e3e40ed8cb12650e9855ae0b9649d8 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/SystemComm.h (.../SystemComm.h) (revision ab304e2ca6e3e40ed8cb12650e9855ae0b9649d8) +++ firmware/App/Services/SystemComm.h (.../SystemComm.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -60,7 +60,8 @@ BOOL isCANBoxForXmit( CAN_MESSAGE_BOX_T srcCANBox ); BOOL isCANBoxForRecv( CAN_MESSAGE_BOX_T srcCANBox ); - +BOOL isHDCommunicating( void ); BOOL isDGOnlyCANNode( void ); +BOOL addMsgToPendingACKList( MESSAGE_T *msg, COMM_BUFFER_T channel, U08 *msgData, U32 len ); #endif Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -56,19 +56,7 @@ #ifdef DEBUG_ENABLED #define DEBUG_EVENT_MAX_TEXT_LEN 40 #endif - -#pragma pack(push,1) - -/// Heat disinfect data -typedef struct -{ - U32 internalState; ///< Internal state of heat disinfect state machine - F32 elapsedTimeMins; ///< Heat disinfect elapsed time in minutes - U32 currentCycle; ///< Current cycle of the heat disinfect -} DG_HEAT_DISINFECT_DATA_T; -#pragma pack(pop) - // ********** private data ********** static BOOL testerLoggedIn = FALSE; ///< Flag indicates whether tester logged in or not. @@ -667,24 +655,19 @@ * @param currentCycle: Current cycle count of DG heat disinfection * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL broadcastHeatDisinfectData( U32 internalState, F32 minutesElapsed, U32 currentCycle ) +BOOL broadcastHeatDisinfectData( DG_HEAT_DISINFECT_DATA_T *data ) { BOOL result; MESSAGE_T msg; U08 *payloadPtr = msg.payload; - DG_HEAT_DISINFECT_DATA_T payload; // create a message record blankMessage( &msg ); msg.hdr.msgID = MSG_ID_DG_HEAT_DISINFECT_DATA; msg.hdr.payloadLen = sizeof( DG_HEAT_DISINFECT_DATA_T ); - payload.internalState = internalState; - payload.elapsedTimeMins = minutesElapsed; - payload.currentCycle = currentCycle; + memcpy( payloadPtr, data, sizeof( DG_HEAT_DISINFECT_DATA_T ) ); - memcpy( payloadPtr, &payload, sizeof( DG_HEAT_DISINFECT_DATA_T ) ); - // serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); @@ -2183,7 +2166,7 @@ * @param message a pointer to the message to handle * @return none *************************************************************************/ -void handleUVReactorsDataPunlishIntervalOverride( MESSAGE_T *message ) +void handleUVReactorsDataPublishIntervalOverride( MESSAGE_T *message ) { TEST_OVERRIDE_PAYLOAD_T payload; BOOL result = FALSE; @@ -2272,4 +2255,132 @@ return result; } +/*********************************************************************//** +* @brief +* The handleUVReactorsHealthOverride function handles UV reactors health +* status override. +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleUVReactorsHealthOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetUVReactorHealthOverride( payload.index, (BOOL)payload.state.u32 ); + } + else + { + result = testResetUVReactorHealthOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleThermistorsDataPublishIntervalOverride function handles a request +* to override the publish interval of the thermistors data +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleThermistorsDataPublishIntervalOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetThermistorPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetThermistorPublishIntervalOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleThermisotrsValueOverride function handles a request to override +* a thermistor's value +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleThermisotrsValueOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetMeasuredThermistorOverride( payload.index, payload.state.f32 ); + } + else + { + result = testResetMeasuredThermistorOverride( payload.index ); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** +* @brief +* The handleROPumpDutyCycleOverride function handles a request to override +* the RO pumps duty cycle +* @details Inputs: none +* @details Outputs: message handled +* @param message a pointer to the message to handle +* @return none +*************************************************************************/ +void handleROPumpDutyCycleOverride( MESSAGE_T *message ) +{ + TEST_OVERRIDE_PAYLOAD_T payload; + BOOL result = FALSE; + + // verify payload length + if ( sizeof(TEST_OVERRIDE_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetTargetDutyCycleOverride( payload.state.f32 ); + } + else + { + result = testResetTargetDutyCyceOverride(); + } + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -rd00ad426d849083922332f832e88e7137a1cad60 -r62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision d00ad426d849083922332f832e88e7137a1cad60) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 62a4d7b976107f7ac4d5013ce06f38f4a0bf65bd) @@ -24,7 +24,8 @@ #include "ROPump.h" #include "UVReactors.h" #include "Thermistors.h" -#include "Fans.h" +#include "Fans.h" +#include "ModeHeatDisinfect.h" /** * @defgroup SystemCommMessages SystemCommMessages @@ -120,7 +121,7 @@ BOOL broadcastTemperatureSensorsData ( U08 *sensorsValue, U32 byteLength ); //MSG_ID_DG_HEAT_DISINFECT_DATA -BOOL broadcastHeatDisinfectData( U32 internalState, F32 minutesElapsed, U32 currentCycle ); +BOOL broadcastHeatDisinfectData( DG_HEAT_DISINFECT_DATA_T *data ); // MSG_ID_DG_UV_REACTORS_DATA BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData ); @@ -250,14 +251,26 @@ BOOL handleStartStopInletUVReactor( MESSAGE_T *message ); //MSG_ID_UV_REACTORS_DATA_PUBLISH_INTERVAL_OVERRIDE -void handleUVReactorsDataPunlishIntervalOverride( MESSAGE_T *message ); +void handleUVReactorsDataPublishIntervalOverride( MESSAGE_T *message ); // MSG_ID_DG_FANS_DATA_PUBLISH_OVERRIDE -void handleFansDataPublishIntervalOverride( MESSAGE_T * message ); +void handleFansDataPublishIntervalOverride( MESSAGE_T *message ); // MSG_ID_DG_START_STOP_OUTLET_UV_REACTOR BOOL handleStartStopOutletUVReactor( MESSAGE_T *message ); +// MSG_ID_DG_UV_REACTORS_HEALTH_OVERRIDE +void handleUVReactorsHealthOverride( MESSAGE_T *message ); + +// MSG_ID_DG_THERMISTORS_DATA_PUBLISH_INTERVAL_OVERRIDE +void handleThermistorsDataPublishIntervalOverride( MESSAGE_T *message ); + +// MSG_ID_DG_THERMISTORS_VALUE_OVERRIDE +void handleThermisotrsValueOverride( MESSAGE_T *message ); + +// MSG_ID_DG_RO_PUMP_DUTY_CYCLE_OVERRIDE +void handleROPumpDutyCycleOverride( MESSAGE_T *message ); + /**@}*/ #endif