Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u -r273f797e1b0f70a9d5720d1ffff29d26ff5144af -r80028d3b1eef322950c1a5b74c282df2ba989ff5 --- firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 273f797e1b0f70a9d5720d1ffff29d26ff5144af) +++ firmware/App/Controllers/ConcentratePumps.c (.../ConcentratePumps.c) (revision 80028d3b1eef322950c1a5b74c282df2ba989ff5) @@ -18,6 +18,7 @@ #include "ConcentratePumps.h" #include "FPGA.h" +#include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -34,6 +35,7 @@ #define CONCENTRATE_PUMP_SPEED_INCREMENT 8.0 ///< Speed increase (mL/min) when controlling concentrate pump to target step speed. #define CONCENTRATE_PUMP_MIN_SPEED 3.0 ///< Minimum speed for concentrate pump in mL per min. #define CONCENTRATE_PUMP_MAX_SPEED 49.0 ///< Maximum speed for concentrate pump in mL per min. +#define CONCENTRATE_PUMP_ERROR_TOLERANCE 0.02 ///< Measured speed needs to be within 2% of commanded speed. #define CONCENTRATE_PUMP_VOLUME_PER_REV 0.15 ///< Volume output every revolution (mL). #define CONCENTRATE_PUMP_PULSE_PER_REV 4.0 ///< Number of pulses generate for every revolution. @@ -48,6 +50,7 @@ #define CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is monitored. #define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 500 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. +#define CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for concentrate pump speed control error. /// Enumeration of concentrate pump states. typedef enum ConcentratePumpState @@ -70,6 +73,7 @@ static F32 pumpTargetSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Target concentrate pumps' speed (mL/min). static F32 currentPumpSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Current controlled concentrate pumps' speed (mL/min). +static OVERRIDE_F32_T measuredPumpSpeed[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Measured concentrate pump speed (mL/min). static U16 togglePeriodCount[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). // ********** private function prototypes ********** @@ -80,6 +84,7 @@ static void stepConcentratePumpToTargetSpeed( CONCENTRATE_PUMPS_T pumpId ); static CONCENTRATE_PUMP_STATE_T handleConcentratePumpOnState( void ); static U32 getPublishConcentratePumpDataInterval( void ); +static F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ); /*********************************************************************//** * @brief @@ -97,6 +102,11 @@ concentratePumpMonitorTimerCounter = 0; stopConcentratePump(); + + initPersistentAlarm( PERSISTENT_ALARM_CP1_SPEED_CONTROL_ERROR, ALARM_ID_CP1_SPEED_CONTROL_ERROR, + TRUE, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_CP2_SPEED_CONTROL_ERROR, ALARM_ID_CP2_SPEED_CONTROL_ERROR, + TRUE, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_SPEED_CONTROL_PERSISTENCE_PERIOD ); } /*********************************************************************//** @@ -111,19 +121,25 @@ if ( ++concentratePumpMonitorTimerCounter >= getPublishConcentratePumpDataInterval() ) { CONCENTRATE_PUMP_DATA_T data; - concentratePumpMonitorTimerCounter = 0U; F32 const cp1PulseWidthInSecond = (F32)( getFPGACP1HallSensePulseWidth() * CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION ) / US_PER_SECOND; F32 const cp2PulseWidthInSecond = (F32)( getFPGACP2HallSensePulseWidth() * CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION ) / US_PER_SECOND; - F32 const cp1SpeedMlPerMin = ( 1 / cp1PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; - F32 const cp2SpeedMlPerMin = ( 1 / cp2PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + measuredPumpSpeed[ CONCENTRATEPUMPS_CP1 ].data = ( 1 / cp1PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + measuredPumpSpeed[ CONCENTRATEPUMPS_CP2 ].data = ( 1 / cp2PulseWidthInSecond ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + F32 const cp1Error = fabs( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1 ) - pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ] ) / pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ]; + F32 const cp2Error = fabs( getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2 ) - pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ] ) / pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ]; + data.cp1TargetSpeed = pumpTargetSpeed[ CONCENTRATEPUMPS_CP1 ]; - data.cp1MeasuredSpeed = cp1SpeedMlPerMin; + data.cp1MeasuredSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1 ); data.cp2TargetSpeed = pumpTargetSpeed[ CONCENTRATEPUMPS_CP2 ]; - data.cp2MeasuredSpeed = cp2SpeedMlPerMin; + data.cp2MeasuredSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2 ); + checkPersistentAlarm( PERSISTENT_ALARM_CP1_SPEED_CONTROL_ERROR, cp1Error > CONCENTRATE_PUMP_ERROR_TOLERANCE, cp1Error ); + checkPersistentAlarm( PERSISTENT_ALARM_CP2_SPEED_CONTROL_ERROR, cp2Error > CONCENTRATE_PUMP_ERROR_TOLERANCE, cp2Error ); + + concentratePumpMonitorTimerCounter = 0U; broadcastConcentratePumpData( &data ); } } @@ -227,6 +243,7 @@ { pumpTargetSpeed[ ii ] = 0.0; currentPumpSpeed[ ii ] = 0.0; + measuredPumpSpeed[ ii ].data = 0.0; } setFPGACP1Control( CONCENTRATE_PUMP_OFF_CONTROL ); @@ -353,7 +370,36 @@ return result; } +/*********************************************************************//** + * @brief + * The getMeasuredPumpSpeed function gets the measured concentrate pump flow rate. + * @details Inputs: measuredPumpSpeed + * @details Outputs: none + * @param pumpId concentrate pump id to increase current step speed + * @return the current concentrate pump flow rate (in mL/min). + *************************************************************************/ +static F32 getMeasuredPumpSpeed( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 result = 0.0; + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + result = measuredPumpSpeed[ pumpId ].data; + + if ( OVERRIDE_KEY == measuredPumpSpeed[ pumpId ].override ) + { + result = measuredPumpSpeed[ pumpId ].ovData; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return result; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -432,4 +478,51 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetConcentratePumpMeasuredSpeedOverride function overrides the + * measured speed value of given concentrate pump id. + * @details Inputs: none + * @details Outputs: measuredPumpSpeed[] + * @param pumpId concentrate pump id + * @param value override concentrate pump measured speed + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetConcentratePumpMeasuredSpeedOverride( U32 pumpId, F32 value ) +{ + BOOL result = FALSE; + + if ( ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) && isTestingActivated() ) + { + result = TRUE; + measuredPumpSpeed[ pumpId ].ovData = value; + measuredPumpSpeed[ pumpId ].override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetConcentratePumpMeasuredSpeedOverride function resets the + * measured speed value of given concentrate pump id. + * @details Inputs: none + * @details Outputs: measuredPumpSpeed[] + * @param pumpId concentrate pump id + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetConcentratePumpMeasuredSpeedOverride( U32 pumpId ) +{ + BOOL result = FALSE; + + if ( ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) && isTestingActivated() ) + { + result = TRUE; + measuredPumpSpeed[ pumpId ].ovData = 0.0; + measuredPumpSpeed[ pumpId ].override = OVERRIDE_RESET; + } + + return result; +} + /**@}*/