Index: firmware/App/Controllers/ConcentratePumps.c =================================================================== diff -u --- firmware/App/Controllers/ConcentratePumps.c (revision 0) +++ firmware/App/Controllers/ConcentratePumps.c (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -0,0 +1,1315 @@ +/************************************************************************** +* +* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file ConcentratePumps.c +* +* @author (last) Vinayakam Mani +* @date (last) 18-Sep-2024 +* +* @author (original) Vinayakam Mani +* @date (original) 18-Sep-2024 +* +***************************************************************************/ +#include + +#include "ConcentratePumps.h" +#include "FpgaDD.h" +#include "MessageSupport.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "TaskGeneral.h" +#include "Utilities.h" + +/** + * @addtogroup ConcentratePumps + * @{ + */ + +// ********** private definitions ********** +//TODO : The definitions of pump direction is differ from HDD, need to revisit. +#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 2.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. +#define CONCENTRATE_PUMP_LOW_SPEED_THRESHOLD_MLPM 10.0F ///< Concentrate pump low speed threshold in mL/min. +#define CONCENTRATE_PUMP_ZERO_FLOW_RATE 0xFFFF ///< Pulse width value when zero flow rate or pump is off. + +#define CONCENTRATE_PUMP_VOLUME_PER_REV 0.1F ///< Volume output every revolution (mL). +#define CONCENTRATE_PUMP_PULSE_PER_REV 2.0F ///< Number of pulses generate for every revolution. +#define CONCENTRATE_PUMP_STEP_PER_REV 200.0F ///< Number of steps for every revolution. +#define CONCENTRATE_PUMP_HALL_SENSE_PERIOD_RESOLUTION 100.0F ///< Hall sense period resolution in microseconds. +#define CONCENTRATE_PUMP_MIN_ALLOWED_HALL_SENSOR_COUNT 1000 ///< Hall sensors minimum allowed value. +#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_STEP_PERIOD_RESOLUTION ( 0.5F / ( US_PER_SECOND * SEC_PER_MIN ) ) ///< Convert step period resolution (0.5 us) to minute. + +/// Volume output per pulse. +#define CONCENTRATE_PUMP_VOLUME_PER_PULSE ( CONCENTRATE_PUMP_VOLUME_PER_REV / CONCENTRATE_PUMP_PULSE_PER_REV ) + +#define CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is monitored. +#define CONCENTRATE_PUMP_CONTROL_INTERVAL ( 1 * MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the concentrate pump is controlled. +#define CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Concentrate pumps speed out of range timeout in milliseconds. + +#define NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK 1 ///< Number of acid and bicarb non-volatile data to check. + +#define DATA_PUBLISH_COUNTER_START_COUNT 0 ///< Data publish counter start count. + +#define CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD 500 ///< Concentrate pump fault persistence period in milliseconds. +#define CONCENTRATE_PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD_MLPM 5.0F ///< Concentrate pump transition to ramp to target speed threshold in mL/min. + +#define CONCENTRATE_PUMP_CONTROL_EIGHTH_STEP 0x07 ///< Concentrate pump control 1/8th step. +#define CONCENTRATE_PUMP_CONTROL_REVERSE_DIR 0x00 ///< Concentrate pump control reverse direction. +#define CONCENTRATE_PUMP_CONTROL_FORWARD_DIR 0x08 ///< Concentrate pump control forward direction. +#define CONCENTRATE_PUMP_CONTROL_ENABLE 0x00 ///< Concentrate pump control enable pump. +#define CONCENTRATE_PUMP_CONTROL_DISABLE 0x01 ///< Concentrate pump control disable pump. +#define CONCENTRATE_PUMP_CONTROL_NOT_RESET 0x20 ///< Concentrate pump control not reset. +#define CONCENTRATE_PUMP_CONTROL_SLEEP_OFF 0x40 ///< Concentrate pump control sleep off. + +static const U32 CONCENTRATE_PUMP_CONTROL_FORWARD = CONCENTRATE_PUMP_CONTROL_SLEEP_OFF | + CONCENTRATE_PUMP_CONTROL_NOT_RESET | + CONCENTRATE_PUMP_CONTROL_ENABLE | + CONCENTRATE_PUMP_CONTROL_FORWARD_DIR | + CONCENTRATE_PUMP_CONTROL_EIGHTH_STEP; ///< Concentrate pump control forward. + +static const U32 CONCENTRATE_PUMP_CONTROL_REVERSE = CONCENTRATE_PUMP_CONTROL_SLEEP_OFF | + CONCENTRATE_PUMP_CONTROL_NOT_RESET | + CONCENTRATE_PUMP_CONTROL_ENABLE | + CONCENTRATE_PUMP_CONTROL_REVERSE_DIR | + CONCENTRATE_PUMP_CONTROL_EIGHTH_STEP; ///< Concentrate pump control reverse. + + +/// Enumeration of concentrate pump states. +typedef enum ConcentratePumpState +{ + CONCENTRATE_PUMP_OFF_STATE = 0, ///< Concentrate pump off state. + CONCENTRATE_PUMP_RAMP_TO_TARGET_SPEED_STATE, ///< Concentrate pump ramp to target state. + CONCENTRATE_PUMP_CONTROL_TARGET_SPEED_STATE, ///< Concentrate pump on state. + NUM_OF_CONCENTRATE_PUMP_STATES ///< Number of concentrate pump states. +} CONCENTRATE_PUMP_STATE_T; + +/// Concentrate pump data structure +typedef struct +{ + U32 controlTimerCounter; ///< Timer counter to perform control on concentrate pump. + CONCENTRATE_PUMP_STATE_T execState; ///< Concentrate pump execute current state. + BOOL hasTurnOnPumpsBeenRequested; ///< Flag indicates a request to turn concentrate pumps on. + OVERRIDE_U32_T hasParkBeenRequested; ///< Flag indicates a request to park the pump. + OVERRIDE_F32_T pumpTargetSpeed; ///< Target concentrate pumps' speed (mL/min). + F32 currentPumpSpeed; ///< Current controlled concentrate pumps' speed (mL/min). + OVERRIDE_F32_T measuredPumpSpeed; ///< Measured concentrate pump speed (mL/min). + U16 togglePeriodCount; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). + U08 direction; ///< Concentrate pump motor direction. + U08 controlSet; ///< Concentrate pump control set. (Used in DVT) + F32 pulseWidthUS; ///< Concentrate pump pulse width in microseconds. + OVERRIDE_U32_T parked; ///< Concentrate pump is currently parked (T/F). + OVERRIDE_U32_T parkFaulted; ///< Concentrate pump park command has faulted (T/F). + BOOL isConcPumpParkInProgress; ///< Concentrate pump park progress boolean flag (T/F). +} CONCENTRATE_PUMP_T; + +// ********** private data ********** + +static U32 concentratePumpMonitorTimerCounter; ///< Timer counter to perform monitor on concentrate pump. +static BOOL acidConcentratePumpParkPersistenceClear; ///< Boolean acid park persistence clearing. +static BOOL bicarbConcentratePumpParkPersistenceClear; ///< Boolean for bicard park persistence clearing. + +/// Concentrate pump data publish interval. +static OVERRIDE_U32_T concentratePumpDataPublishInterval = { CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL, CONCENTRATE_PUMP_DATA_PUBLISH_INTERVAL, 0, 0 }; + +static CONCENTRATE_PUMP_T concentratePumps[ NUM_OF_CONCENTRATE_PUMPS ]; ///< Array of concentrate pumps' data structure. +//static DD_ACID_CONCENTRATES_RECORD_T acidConcentrateCalRecord; ///< Acid concentrate calibration record. +//static DD_BICARB_CONCENTRATES_RECORD_T bicarbConcentrateCalRecord; ///< Bicarb concentrate calibration record. +//static DD_CONC_PUMPS_CAL_RECORD_T concentratePumpsCalRecord; ///< Concentrate pumps calibration record. + +// ********** private function prototypes ********** + +static void stopConcentratePump( CONCENTRATE_PUMPS_T pumpId ); +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpOffState( CONCENTRATE_PUMPS_T pumpId ); +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpRampToTargetSpeedState( CONCENTRATE_PUMPS_T pumpId ); +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpControlTargetSpeedState( CONCENTRATE_PUMPS_T pumpId ); +static BOOL stepConcentratePumpToTargetSpeed( CONCENTRATE_PUMPS_T pumpId ); +static void calcMeasuredPumpsSpeed( void ); +static void monitorPumpSpeed( CONCENTRATE_PUMPS_T pumpId, ALARM_ID_T alarm ); +static void checkConcentratePumpControlSet( CONCENTRATE_PUMPS_T pumpId ); +static void publishConcentratePumpData( void ); + +/*********************************************************************//** + * @brief + * The initConcentratePump function initializes the ConcentratePumps unit. + * @details \b Inputs: none + * @details \b Outputs: ConcentratePumps unit variables initialized + * @return none + *************************************************************************/ +void initConcentratePump( void ) +{ + CONCENTRATE_PUMPS_T pumpId; + + concentratePumpMonitorTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + acidConcentratePumpParkPersistenceClear = FALSE; + bicarbConcentratePumpParkPersistenceClear = FALSE; + + for ( pumpId = CONCENTRATEPUMPS_CP1_ACID; pumpId < NUM_OF_CONCENTRATE_PUMPS; pumpId++ ) + { + concentratePumps[ pumpId ].controlTimerCounter = 0; + concentratePumps[ pumpId ].execState = CONCENTRATE_PUMP_OFF_STATE; + concentratePumps[ pumpId ].measuredPumpSpeed.data = 0.0F; + concentratePumps[ pumpId ].measuredPumpSpeed.ovInitData = 0.0F; + concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested = FALSE; + concentratePumps[ pumpId ].hasParkBeenRequested.data = FALSE; + concentratePumps[ pumpId ].hasParkBeenRequested.ovInitData = FALSE; + concentratePumps[ pumpId ].parked.data = FALSE; + concentratePumps[ pumpId ].parked.ovInitData = FALSE; + concentratePumps[ pumpId ].parkFaulted.data = FALSE; + concentratePumps[ pumpId ].parkFaulted.ovInitData = FALSE; + concentratePumps[ pumpId ].pumpTargetSpeed.data = 0.0F; + concentratePumps[ pumpId ].pumpTargetSpeed.ovInitData = 0.0F; + concentratePumps[ pumpId ].direction = CONCENTRATE_PUMP_FORWARD_DIR; + concentratePumps[ pumpId ].controlSet = CONCENTRATE_PUMP_CONTROL_FORWARD; + concentratePumps[ pumpId ].isConcPumpParkInProgress = FALSE; + stopConcentratePump( pumpId ); + } + + initPersistentAlarm( ALARM_ID_DD_CP1_SPEED_CONTROL_ERROR, 0, CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DD_CP2_SPEED_CONTROL_ERROR, 0, CONCENTRATE_PUMP_SPEED_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DD_CONC_PUMP_HALL_SENSOR_OUT_OF_RANGE, CONCENTRATE_PUMP_HALL_SENSORS_OUT_OF_RANGE_TIME_MS, CONCENTRATE_PUMP_HALL_SENSORS_OUT_OF_RANGE_TIME_MS ); + initPersistentAlarm( ALARM_ID_DD_CONCENTRATE_PUMP_FAULT, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD ); +} + +/*********************************************************************//** + * @brief + * The execConcentratePumpMonitor function executes the concentrate pump monitor. + * @details \b Inputs: none + * @details \b Outputs: publish concentrate pump data + * @details \b Alarm: ALARM_ID_DD_CONCENTRATE_PUMP_FAULT when FPGA reports any + * pump fault. + * @return none + *************************************************************************/ +void execConcentratePumpMonitor( void ) +{ + U08 fpgaConcPumpsFault = getFPGAConcentratePumpsFault(); + BOOL isConcPumpFault = ( fpgaConcPumpsFault > 0 ? TRUE : FALSE ); + + // Check if a new calibration is available +// if ( TRUE == isNewCalibrationRecordAvailable() ) +// { +// // Get the calibration values of acid and bicarb +// getNVRecord2Driver( GET_CAL_ACID_CONCENTREATES, (U08*)&acidConcentrateCalRecord, sizeof( acidConcentrateCalRecord ), +// NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK, ALARM_ID_DD_ACID_CONCENTRATE_INVALID_CAL_RECORD ); +// getNVRecord2Driver( GET_CAL_BICARB_CONCENTRATES, (U08*)&bicarbConcentrateCalRecord, sizeof( bicarbConcentrateCalRecord ), +// NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK, ALARM_ID_DD_BICARB_CONCENTRATE_INVALID_CAL_RECORD ); +// } + + // Calculate pump speed for each defined pump + calcMeasuredPumpsSpeed(); + + concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].parked.data = (U32)getFPGAAcidPumpIsParked(); + concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].parked.data = (U32)getFPGABicarbPumpIsParked(); + concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].parkFaulted.data = (U32)getFPGAAcidPumpParkFault(); + concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].parkFaulted.data = (U32)getFPGABicarbPumpParkFault(); + + if ( ( TRUE == getConcPumpIsParked( CONCENTRATEPUMPS_CP1_ACID ) ) || ( TRUE == getConcPumpParkIsFaulted( CONCENTRATEPUMPS_CP1_ACID ) ) ) + { + // If the pump has parked or faulted during the park, then it is not in progress + concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].isConcPumpParkInProgress = FALSE; + } + if ( ( TRUE == getConcPumpIsParked( CONCENTRATEPUMPS_CP2_BICARB ) ) || ( TRUE == getConcPumpParkIsFaulted( CONCENTRATEPUMPS_CP2_BICARB ) ) ) + { + concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].isConcPumpParkInProgress = FALSE; + } + + // Don't monitor persistence for cp speed alarms if we parked. + if ( TRUE == acidConcentratePumpParkPersistenceClear ) + { + // Clear flag and resume persistence checking once park bit is set. + if ( TRUE == getConcPumpIsParked( CONCENTRATEPUMPS_CP1_ACID ) ) + { + acidConcentratePumpParkPersistenceClear = FALSE; + } + else + { + resetPersistentAlarmTimer( ALARM_ID_DD_CP1_SPEED_CONTROL_ERROR ); + } + } + + if ( TRUE == bicarbConcentratePumpParkPersistenceClear ) + { + // Clear flag and resume persistence checking once park bit is set. + if ( TRUE == getConcPumpIsParked( CONCENTRATEPUMPS_CP2_BICARB ) ) + { + bicarbConcentratePumpParkPersistenceClear = FALSE; + } + else + { + resetPersistentAlarmTimer( ALARM_ID_DD_CP2_SPEED_CONTROL_ERROR ); + } + } + + monitorPumpSpeed( CONCENTRATEPUMPS_CP1_ACID, ALARM_ID_DD_CP1_SPEED_CONTROL_ERROR ); + monitorPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB, ALARM_ID_DD_CP2_SPEED_CONTROL_ERROR ); + + checkPersistentAlarm( ALARM_ID_DD_CONCENTRATE_PUMP_FAULT, isConcPumpFault, fpgaConcPumpsFault, CONCENTRATE_PUMP_FAULT_PERSISTENCE_PERIOD ); + + //Publish concentrate pump data + publishConcentratePumpData(); +} + +/*********************************************************************//** + * @brief + * The execConcentratePumpController function executes the concentrate pump controller. + * @details \b Inputs: execState + * @details \b Outputs: execState + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump state is seen. + * @return none + *************************************************************************/ +void execConcentratePumpController( void ) +{ + CONCENTRATE_PUMPS_T pumpId; + + for ( pumpId = CONCENTRATEPUMPS_CP1_ACID; pumpId < NUM_OF_CONCENTRATE_PUMPS; pumpId++ ) + { + switch ( concentratePumps[ pumpId ].execState ) + { + case CONCENTRATE_PUMP_OFF_STATE: + concentratePumps[ pumpId ].execState = handleConcentratePumpOffState( pumpId ); + break; + + case CONCENTRATE_PUMP_RAMP_TO_TARGET_SPEED_STATE: + concentratePumps[ pumpId ].execState = handleConcentratePumpRampToTargetSpeedState( pumpId ); + break; + + case CONCENTRATE_PUMP_CONTROL_TARGET_SPEED_STATE: + 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 + } + } +} + +/*********************************************************************//** + * @brief + * The execConcenratePumpsSelfTest function executes the concentrate pumps + * self-test. + * @details \b Inputs: none + * @details \b Outputs: none + * @return ConcentratepumpSelfTestResult (SELF_TEST_STATUS_T) + *************************************************************************/ +SELF_TEST_STATUS_T execConcenratePumpsSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; +// BOOL calStatus = FALSE; + +// calStatus |= getNVRecord2Driver( GET_CAL_ACID_CONCENTREATES, (U08*)&acidConcentrateCalRecord, sizeof( DD_ACID_CONCENTRATES_RECORD_T ), +// NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK, ALARM_ID_DD_ACID_CONCENTRATE_INVALID_CAL_RECORD ); +// +// calStatus |= getNVRecord2Driver( GET_CAL_BICARB_CONCENTRATES, (U08*)&bicarbConcentrateCalRecord, sizeof( DD_BICARB_CONCENTRATES_RECORD_T ), +// NUMBER_OF_ACID_AND_BICARB_NV_DATA_TO_CHECK, ALARM_ID_DD_BICARB_CONCENTRATE_INVALID_CAL_RECORD ); +// +// calStatus |= getNVRecord2Driver( GET_CAL_CONCENTRATE_PUMPS_RECORD, (U08*)&concentratePumpsCalRecord, sizeof( DD_CONC_PUMPS_CAL_RECORD_T ), +// NUM_OF_CAL_DATA_DD_CONC_PUMPS, ALARM_ID_NO_ALARM ); +// +// result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + + return result; +} + +/*********************************************************************//** + * @brief + * The requestConcentratePumpOn function requests the module to turn on + * the concentrate pumps. + * @details \b Inputs: none + * @details \b Outputs: set flag isPumpOnRequested to TRUE + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id + * @return none + *************************************************************************/ +void requestConcentratePumpOn( CONCENTRATE_PUMPS_T pumpId ) +{ + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested = TRUE; + acidConcentratePumpParkPersistenceClear = FALSE; + bicarbConcentratePumpParkPersistenceClear = FALSE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + +/*********************************************************************//** + * @brief + * The handleConcentratePumpParkRequest function accepts/rejects the park + * concentrate pumps request. + * @details \b Inputs: Pump state and DD operating mode + * @details \b Outputs: command response set to true if able to perform parking pump. + * @return result as true if park is accomplished. + *************************************************************************/ +BOOL handleConcentratePumpParkRequest( void ) +{ + BOOL result = FALSE; + DD_OP_MODE_T opMode = getCurrentOperationMode(); + + // pumps should be not ON and DD operation mode is not in fault mode + if ( ( concentratePumps[CONCENTRATEPUMPS_CP1_ACID].execState == CONCENTRATE_PUMP_OFF_STATE ) && + ( concentratePumps[CONCENTRATEPUMPS_CP2_BICARB].execState == CONCENTRATE_PUMP_OFF_STATE ) && + //( DD_MODE_FILL != opMode ) && + ( DD_MODE_FAUL != opMode ) ) + { + // Park concentrate pump + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, PARK_CONC_PUMPS ); + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The isConcPumpParkInProgress function requests whether the concentrate + * pump park is in progress or not. + * @details \b Inputs: concentratePumps + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id + * @return TRUE if the concentrate pump park is in progress otherwise, FALSE + *************************************************************************/ +BOOL isConcPumpParkInProgress( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL status = FALSE; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + status = concentratePumps[ pumpId ].isConcPumpParkInProgress; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The requestConcentratePumpOff function requests the module to turn off + * the concentrate pumps. + * @details \b Inputs: none + * @details \b Outputs: set flag isPumpOffRequested to TRUE + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id + * @param park TRUE if pump should be parked, FALSE if not + * @return none + *************************************************************************/ +void requestConcentratePumpOff( CONCENTRATE_PUMPS_T pumpId, BOOL park ) +{ + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested = FALSE; + concentratePumps[ pumpId ].hasParkBeenRequested.data = park; + concentratePumps[ pumpId ].pumpTargetSpeed.data = 0.0F; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + +/*********************************************************************//** + * @brief + * The setConcentratePumpTargetSpeed function sets the target step speed based on + * given speed in mL/min to specified concentrate pump. + * @details \b Inputs: none + * @details \b Outputs: set target step speed for given pump + * @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 + * @return none + *************************************************************************/ +void setConcentratePumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId, F32 targetSpeed_ml_min ) +{ + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( targetSpeed_ml_min >= 0.0 ) + { + concentratePumps[ pumpId ].direction = CONCENTRATE_PUMP_FORWARD_DIR; + concentratePumps[ pumpId ].controlSet = CONCENTRATE_PUMP_CONTROL_FORWARD; + } + else + { + concentratePumps[ pumpId ].direction = CONCENTRATE_PUMP_REVERSE_DIR; + concentratePumps[ pumpId ].controlSet = CONCENTRATE_PUMP_CONTROL_REVERSE; + targetSpeed_ml_min *= -1.0; + } + + /* + * If 3 <= speed <= 48 set it + * If speed < 3 set to 0 + * else speed > 48 set to 48 + */ + if ( ( CONCENTRATE_PUMP_MIN_SPEED <= targetSpeed_ml_min ) && ( targetSpeed_ml_min <= CONCENTRATE_PUMP_MAX_SPEED ) ) + { + concentratePumps[ pumpId ].pumpTargetSpeed.data = targetSpeed_ml_min; + } + else if ( targetSpeed_ml_min < CONCENTRATE_PUMP_MIN_SPEED ) + { + concentratePumps[ pumpId ].pumpTargetSpeed.data = 0.0; + } + else + { + concentratePumps[ pumpId ].pumpTargetSpeed.data = CONCENTRATE_PUMP_MAX_SPEED; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + +/*********************************************************************//** + * @brief + * The getConcentratePumpTargetFlowMLPM function returns the concentrate pump's + * flow rate in mL/min. + * @details \b Inputs: concentratePumps + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to get its target flow + * @return the current concentrate pump flow rate (in mL/min). + *************************************************************************/ +F32 getConcentratePumpTargetFlowMLPM( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 flow = 0.0; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + flow = getPumpTargetSpeed( pumpId ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return flow; +} + +/*********************************************************************//** + * @brief + * The getPumpTargetSpeed function gets the concentrate pump target spped. + * @details \b Inputs: pumpTargetSpeed + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to get the target speed + * @return the current concentrate pump target speed. + *************************************************************************/ +F32 getPumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 speed = 0.0F; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + speed = getF32OverrideValue( &concentratePumps[ pumpId ].pumpTargetSpeed ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return speed; +} + +/*********************************************************************//** + * @brief + * The getMeasuredPumpSpeedMLPM function gets the measured concentrate pump flow rate. + * @details \b Inputs: measuredPumpSpeed + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to increase current step speed + * @return the current concentrate pump flow rate (in mL/min). + *************************************************************************/ +F32 getMeasuredPumpSpeedMLPM( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 speed = 0.0F; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + speed = getF32OverrideValue( &concentratePumps[ pumpId ].measuredPumpSpeed ); + speed = ( CONCENTRATE_PUMP_REVERSE_DIR == concentratePumps[ pumpId ].direction ? speed * -1.0F : speed ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return speed; +} + +/*********************************************************************//** + * @brief + * The getConcPumpParkRequest function gets the current park request state for a + * given pump. + * @details \b Inputs: hasParkBeenRequested + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to get park request state for + * @return the current concentrate pump park request. + *************************************************************************/ +BOOL getConcPumpParkRequest( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL result = FALSE; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + result = (BOOL)getU32OverrideValue( &concentratePumps[ pumpId ].hasParkBeenRequested ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getConcPumpIsParked function gets the current parked state for a + * given pump. + * @details \b Inputs: parked + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to get parked state for + * @return the current concentrate pump parked state. + *************************************************************************/ +BOOL getConcPumpIsParked( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL result = FALSE; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + result = (BOOL)getU32OverrideValue( &concentratePumps[ pumpId ].parked ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getConcPumpParkIsFaulted function gets the current park command + * fault state for a given pump. + * @details \b Inputs: parkFaulted + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id to get park faulted state for + * @return the current concentrate pump park faulted state. + *************************************************************************/ +BOOL getConcPumpParkIsFaulted( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL result = FALSE; + + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + result = (BOOL)getU32OverrideValue( &concentratePumps[ pumpId ].parkFaulted ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The stopConcentratePump function sets the concentrate pump step speed + * to zero and turns off concentrate pump. Also parks the pump if requested. + * @details \b Inputs: none + * @details \b Outputs: concentratePumps + * @param pumpId concentrate pump id + * @return none + *************************************************************************/ +static void stopConcentratePump( CONCENTRATE_PUMPS_T pumpId ) +{ + BOOL parkPump = getConcPumpParkRequest( pumpId ); + + concentratePumps[ pumpId ].hasParkBeenRequested.data = FALSE; // reset park request for next time + concentratePumps[ pumpId ].currentPumpSpeed = 0.0F; // set target rate to zero + + // Send zero rate command to stop the pump + if ( CONCENTRATEPUMPS_CP1_ACID == pumpId ) + { + setFPGAAcidPumpSetStepSpeed( CONCENTRATE_PUMP_ZERO_FLOW_RATE ); + } + else + { + setFPGABicarbSetStepSpeed( CONCENTRATE_PUMP_ZERO_FLOW_RATE ); + } + + // Park concentrate pump too if requested + if ( TRUE == parkPump ) + { + if ( CONCENTRATEPUMPS_CP1_ACID == pumpId ) + { + setFPGAAcidPumpParkCmd(); + acidConcentratePumpParkPersistenceClear = TRUE; + } + else + { + setFPGABicarbPumpParkCmd(); + bicarbConcentratePumpParkPersistenceClear = TRUE; + } + concentratePumps[ pumpId ].isConcPumpParkInProgress = TRUE; + } +} + +/*********************************************************************//** + * @brief + * The handleConcentratePumpOffState function turns on concentrate pumps and + * switch to on state upon request. + * @details \b Inputs: none + * @details \b Outputs: concentrate pumps turn on + * @param pumpId concentrate pump id + * @return state + *************************************************************************/ +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpOffState( CONCENTRATE_PUMPS_T pumpId ) +{ + CONCENTRATE_PUMP_STATE_T state = CONCENTRATE_PUMP_OFF_STATE; + + if ( TRUE == concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + U08 controlSet = concentratePumps[ pumpId ].controlSet; + + if ( CONCENTRATEPUMPS_CP1_ACID == pumpId ) + { + setFPGAAcidPumpControl( controlSet ); + } + else + { + setFPGABicarbPumpControl( controlSet ); + } + + state = CONCENTRATE_PUMP_RAMP_TO_TARGET_SPEED_STATE; + } + + // In case we are in a mode that the concentrate pumps are off but they still need to be parked, then the stop function + // is called to park the pumps + if ( TRUE == getConcPumpParkRequest( pumpId ) ) + { + stopConcentratePump( pumpId ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleConcentratePumpRampToTargetSpeedState function executes the + * concentrate pump ramp up to target speed state. Once the speed is close + * to target the state is transitioned to control target state. + * @details \b Inputs: none + * @details \b Outputs: none + * @param pumpId concentrate pump id + * @return next state of the state machine + *************************************************************************/ +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpRampToTargetSpeedState( CONCENTRATE_PUMPS_T pumpId ) +{ + CONCENTRATE_PUMP_STATE_T state = CONCENTRATE_PUMP_RAMP_TO_TARGET_SPEED_STATE; + + if ( TRUE == stepConcentratePumpToTargetSpeed( pumpId ) ) + { + state = CONCENTRATE_PUMP_CONTROL_TARGET_SPEED_STATE; + } + + if ( FALSE == concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + state = CONCENTRATE_PUMP_OFF_STATE; + stopConcentratePump( pumpId ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleConcentratePumpControlTargetSpeedState function turns off concentrate + * pumps switch to off state upon request. While in on state, the function + * controls concentrate pumps to a target step speed. + * @details \b Inputs: currentPumpSpeed[] + * @details \b Outputs: control concentrate pumps to target step speed + * @param pumpId concentrate pump id + * @return state + *************************************************************************/ +static CONCENTRATE_PUMP_STATE_T handleConcentratePumpControlTargetSpeedState( CONCENTRATE_PUMPS_T pumpId ) +{ + CONCENTRATE_PUMP_STATE_T state = CONCENTRATE_PUMP_CONTROL_TARGET_SPEED_STATE; + F32 targetToCurreSpeedDiffMLPM = fabs( getPumpTargetSpeed( pumpId ) - concentratePumps[ pumpId ].currentPumpSpeed ); + + if ( ++concentratePumps[ pumpId ].controlTimerCounter >= CONCENTRATE_PUMP_CONTROL_INTERVAL ) + { + concentratePumps[ pumpId ].controlTimerCounter = 0; + stepConcentratePumpToTargetSpeed( pumpId ); + } + + if ( targetToCurreSpeedDiffMLPM >= CONCENTRATE_PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD_MLPM ) + { + // If the requested target speed is greater than the threshold, transition back to ramp state regardless of the status of the + // control interval + stepConcentratePumpToTargetSpeed( pumpId ); + state = CONCENTRATE_PUMP_RAMP_TO_TARGET_SPEED_STATE; + } + + if ( FALSE == concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + state = CONCENTRATE_PUMP_OFF_STATE; + stopConcentratePump( pumpId ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The stepConcentratePumpToTargetSpeed function steps current step speed + * toward target speed with predefined step increase. + * @details \b Inputs: none + * @details \b Outputs: currentPumpSpeed[] + * @param pumpId concentrate pump id to increase current step speed + * @return TRUE if the pump has reached to target otherwise, FALSE + *************************************************************************/ +static BOOL stepConcentratePumpToTargetSpeed( CONCENTRATE_PUMPS_T pumpId ) +{ + F32 speedIncrease; + BOOL hasTgtBeenReached = FALSE; + F32 currentToTargetDiff = fabs( getPumpTargetSpeed( pumpId ) - concentratePumps[ pumpId ].currentPumpSpeed ); + + if ( currentToTargetDiff > NEARLY_ZERO ) + { + if ( currentToTargetDiff > CONCENTRATE_PUMP_SPEED_INCREMENT ) + { + speedIncrease = CONCENTRATE_PUMP_SPEED_INCREMENT; + } + else + { + speedIncrease = currentToTargetDiff; + hasTgtBeenReached = TRUE; + } + + // Subtract current speed when target speed is smaller + if ( getPumpTargetSpeed( pumpId ) < concentratePumps[ pumpId ].currentPumpSpeed ) + { + speedIncrease *= -1.0F; + } + + concentratePumps[ pumpId ].currentPumpSpeed += speedIncrease; + + // If the pump's target speed is set to be 0, do not ramp down set it to zero immediately + if ( fabs( getPumpTargetSpeed( pumpId ) < NEARLY_ZERO ) ) + { + concentratePumps[ pumpId ].currentPumpSpeed = 0.0F; + } + } + + if ( concentratePumps[ pumpId ].currentPumpSpeed > NEARLY_ZERO ) + { + F32 timePerStep = CONCENTRATE_PUMP_VOLUME_PER_REV / ( concentratePumps[ pumpId ].currentPumpSpeed * CONCENTRATE_PUMP_STEP_PER_REV ); + F32 stepPeriodCounts = timePerStep / ( CONCENTRATE_PUMP_STEP_PERIOD_RESOLUTION * CONCENTRATE_PUMP_MICRO_STEPS_PER_STEP ); + + concentratePumps[ pumpId ].togglePeriodCount = (U16)( stepPeriodCounts + FLOAT_TO_INT_ROUNDUP_OFFSET ); + } + else + { + concentratePumps[ pumpId ].togglePeriodCount = CONCENTRATE_PUMP_ZERO_FLOW_RATE; + } + + // Check if the control set bit is set as desired and if not, correct it + checkConcentratePumpControlSet( pumpId ); + + if ( CONCENTRATEPUMPS_CP1_ACID == pumpId ) + { + setFPGAAcidPumpSetStepSpeed( concentratePumps[ pumpId ].togglePeriodCount ); + } + else + { + setFPGABicarbSetStepSpeed( concentratePumps[ pumpId ].togglePeriodCount ); + } + + return hasTgtBeenReached; +} + +/*********************************************************************//** + * @brief + * The calcMeasuredPumpsSpeed function iterates through the concentrate + * pumps and calculates the concentrate pump flow. It also checks that + * the hall sensor pulse width count for the concentrate pump is valid. + * @details \b Inputs: none + * @details \b Outputs: measuredPumpSpeed + * @details \b Alarms: ALARM_ID_DD_CONC_PUMP_HALL_SENSOR_OUT_OF_RANGE when + * hall sensor pulse width is out of range. + * @return none + *************************************************************************/ +static void calcMeasuredPumpsSpeed( void ) +{ + CONCENTRATE_PUMPS_T pumpId; + U16 pulseWidthCount = 0; + F32 pulseWidthInMicroSeconds = 0.0F; + BOOL isPulseWidthOut = FALSE; + CONCENTRATE_PUMPS_T pumpInAlarm = CONCENTRATEPUMPS_FIRST; + F32 pumpInAlarmPulseWidthInMicroSeconds = 0.0F; + BOOL isPumpPulseWidthOut = FALSE; + + for ( pumpId = CONCENTRATEPUMPS_FIRST; pumpId < NUM_OF_CONCENTRATE_PUMPS; pumpId++ ) + { + switch ( pumpId ) + { + case CONCENTRATEPUMPS_CP1_ACID: + pulseWidthCount = getFPGACPAHallSensePulseWidth(); + break; + + case CONCENTRATEPUMPS_CP2_BICARB: + pulseWidthCount = getFPGACPBHallSensePulseWidth(); + 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 ); + + // Determine measured speed for the pump + if ( CONCENTRATE_PUMP_ZERO_FLOW_RATE == pulseWidthCount ) + { + concentratePumps[ pumpId ].measuredPumpSpeed.data = 0.0F; + } + else if ( FALSE == isPumpPulseWidthOut ) + { + concentratePumps[ pumpId ].measuredPumpSpeed.data = ( US_PER_SECOND / pulseWidthInMicroSeconds ) * CONCENTRATE_PUMP_VOLUME_PER_PULSE * SEC_PER_MIN; + } + + // If pulse width is out of range capture pump out of range, pumpId and pulse width + if ( TRUE == isPumpPulseWidthOut ) + { + // Pulse width for this concentrate pump is out of range + isPulseWidthOut = TRUE; + pumpInAlarm = pumpId; + pumpInAlarmPulseWidthInMicroSeconds = pulseWidthInMicroSeconds; + } + } + + checkPersistentAlarm( ALARM_ID_DD_CONC_PUMP_HALL_SENSOR_OUT_OF_RANGE, isPulseWidthOut, pumpInAlarm, pumpInAlarmPulseWidthInMicroSeconds ); +} + +/*********************************************************************//** + * @brief + * The monitorPumpSpeed function monitors the concentrate pumps speed and + * triggers the alarms if they are out of range. + * @details \b Inputs: concentratePumps + * @details \b Outputs: none + * @param pumpId pump id to set step speed + * @param alarm which the corresponding alarm of the concentrate pump + * @return none + *************************************************************************/ +static void monitorPumpSpeed( CONCENTRATE_PUMPS_T pumpId, ALARM_ID_T alarm ) +{ + F32 cpTargetSpeed = concentratePumps[ pumpId ].currentPumpSpeed; + F32 cpError = fabs( fabs( getMeasuredPumpSpeedMLPM( pumpId ) ) - cpTargetSpeed ); + BOOL isCpSpeedOut = FALSE; + F32 tolerance = CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_SLOW_MLPM; + + if ( cpTargetSpeed > CONCENTRATE_PUMP_LOW_SPEED_THRESHOLD_MLPM ) + { + // Check if the pump is not in the off state and if it is not and greater than the minimum threshold, divide the error + // to target speed. If the pump is off the target speed is 0 so the speed check is done differently + cpError = cpError / cpTargetSpeed; + tolerance = CONCENTRATE_PUMP_SPD_OUT_OF_RANGE_TOL_WHEN_ON_PCT; + } + + isCpSpeedOut = ( cpError > tolerance ? TRUE : FALSE ); + + checkPersistentAlarm( alarm, isCpSpeedOut, cpError, tolerance ); +} + +/*********************************************************************//** + * @brief + * The checkConcentratePumpControlSet function monitors the status of the + * concentrate pumps control set bit and if they are different from the + * 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 ) + { + case CONCENTRATEPUMPS_CP1_ACID: + controlSetBits = getFPGAAcidPumpControlStatus(); + + if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) + { + setFPGAAcidPumpControl( concentratePumps[ pumpId ].controlSet ); + } + break; + + case CONCENTRATEPUMPS_CP2_BICARB: + controlSetBits = getFPGABicarbPumpControlStatus(); + + if ( controlSetBits != concentratePumps[ pumpId ].controlSet ) + { + setFPGABicarbPumpControl( 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; + } +} + +/*********************************************************************//** + * @brief + * The publishConcentratePumpData function publishes Concentrate pump states + * at the set interval. + * @details \b Inputs: concentratePumpMonitorTimerCounter + * @details \b Outputs: concentratePumpMonitorTimerCounter + * @details \b Messages: MSG_ID_DD_CONCENTRATE_PUMP_DATA to publish concentrate pump states. + * @return none + *************************************************************************/ +static void publishConcentratePumpData( void ) +{ + if ( ++concentratePumpMonitorTimerCounter >= getU32OverrideValue( &concentratePumpDataPublishInterval ) ) + { + CONCENTRATE_PUMP_DATA_T data; + + U08 cp1Direction = concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].direction; + F32 cp1SetSpeed = concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].currentPumpSpeed; + F32 cp1TgtSpeed = getPumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID ); + U08 cp2Direction = concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].direction; + F32 cp2SetSpeed = concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].currentPumpSpeed; + F32 cp2TgtSpeed = getPumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB ); + + // Use the above values to prepare the broadcast data + data.cp1CurrentSetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == cp1Direction ? cp1SetSpeed * -1.0F : cp1SetSpeed ); + data.cp1MeasuredSpeed = getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP1_ACID ); + data.cp1TargetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == cp1Direction ? cp1TgtSpeed * -1.0F : cp1TgtSpeed ); + data.cp2CurrentSetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == cp2Direction ? cp2SetSpeed * -1.0F : cp2SetSpeed ); + data.cp2MeasuredSpeed = getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP2_BICARB ); + data.cp2TargetSpeed = ( CONCENTRATE_PUMP_REVERSE_DIR == cp2Direction ? cp2TgtSpeed * -1.0F : cp2TgtSpeed ); + data.cp1State = concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].execState; + data.cp2State = concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].execState; + data.cp1PulseUS = concentratePumps[ CONCENTRATEPUMPS_CP1_ACID ].pulseWidthUS; + data.cp2PulseUS = concentratePumps[ CONCENTRATEPUMPS_CP2_BICARB ].pulseWidthUS; + data.cp1Parked = getConcPumpIsParked( CONCENTRATEPUMPS_CP1_ACID ); + data.cp2Parked = getConcPumpIsParked( CONCENTRATEPUMPS_CP2_BICARB ); + data.cp1ParkFault = getConcPumpParkIsFaulted( CONCENTRATEPUMPS_CP1_ACID ); + data.cp2ParkFault = getConcPumpParkIsFaulted( CONCENTRATEPUMPS_CP2_BICARB ); + + concentratePumpMonitorTimerCounter = 0; + broadcastData( MSG_ID_DD_CONCENTRATE_PUMP_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( CONCENTRATE_PUMP_DATA_T ) ); + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testConcentratePumpDataPublishIntervalOverride function overrides the + * concentrate pump data publish interval. + * @details \b Inputs: none + * @details \b Outputs: concentratePumpDataPublishInterval + * @param value override concentrate pump data publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testConcentratePumpDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverridePayloadFromMessage( message, &override ); + + // Verify tester has logged in with TD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + U32 intvl = override.state.u32 / TASK_GENERAL_INTERVAL; + + concentratePumpDataPublishInterval.ovData = intvl; + concentratePumpDataPublishInterval.override = OVERRIDE_KEY; + } + else + { + concentratePumpDataPublishInterval.override = OVERRIDE_RESET; + concentratePumpDataPublishInterval.ovData = concentratePumpDataPublishInterval.ovInitData; + } + + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetConcentratePumpTargetSpeedOverride function overrides the target + * speed value of given concentrate pump id. + * @details \b Inputs: none + * @details \b Outputs: pumpTargetSpeed + * @param pumpId concentrate pump id + * @param value override concentrate pump target speed + * @return TRUE if override successful, FALSE if not + * @note pump traget speed range should be between 3.0F and 45.0F. + *************************************************************************/ +BOOL testConcentratePumpTargetSpeedOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &override ); + + // Verify tester has logged in with DD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + U32 pumpId = override.index; + + // Verify concentrate pump index of override + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + F32 value = override.state.f32; + + concentratePumps[ pumpId ].pumpTargetSpeed.ovData = value; + concentratePumps[ pumpId ].pumpTargetSpeed.override = OVERRIDE_KEY; + } + else + { + concentratePumps[ pumpId ].pumpTargetSpeed.override = OVERRIDE_RESET; + concentratePumps[ pumpId ].pumpTargetSpeed.ovData = concentratePumps[ pumpId ].pumpTargetSpeed.ovInitData; + } + + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetConcentratePumpMeasuredSpeedOverride function overrides the + * measured speed value of given concentrate pump id. + * @details \b Inputs: none + * @details \b Outputs: measuredPumpSpeed[] + * @param pumpId concentrate pump id + * @param value override concentrate pump measured speed + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testConcentratePumpMeasuredSpeedOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &override ); + + // Verify tester has logged in with DD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + U32 pumpId = override.index; + + // Verify concentrate pump index of override + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + F32 value = override.state.f32; + + concentratePumps[ pumpId ].measuredPumpSpeed.ovData = value; + concentratePumps[ pumpId ].measuredPumpSpeed.override = OVERRIDE_KEY; + } + else + { + concentratePumps[ pumpId ].measuredPumpSpeed.override = OVERRIDE_RESET; + concentratePumps[ pumpId ].measuredPumpSpeed.ovData = concentratePumps[ pumpId ].measuredPumpSpeed.ovInitData; + } + + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetConcentratePumpParkedOverride function overrides the parked + * status of given concentrate pump id. + * @details \b Inputs: none + * @details \b Outputs: parked[] + * @param pumpId concentrate pump id + * @param value override concentrate pump parked status + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testConcentratePumpParkedOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &override ); + + // Verify tester has logged in with DD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + U32 pumpId = override.index; + + // Verify concentrate pump index of override + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + U32 value = override.state.u32; + + concentratePumps[ pumpId ].parked.ovData = value; + concentratePumps[ pumpId ].parked.override = OVERRIDE_KEY; + } + else + { + concentratePumps[ pumpId ].parked.override = OVERRIDE_RESET; + concentratePumps[ pumpId ].parked.ovData = concentratePumps[ pumpId ].parked.ovInitData; + } + + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetConcentratePumpParkCmdFaultedOverride function overrides the + * park command fault status of given concentrate pump id. + * @details \b Inputs: none + * @details \b Outputs: parkFaulted[] + * @param pumpId concentrate pump id + * @param value override concentrate pump park command faulted status + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testConcentratePumpParkCmdFaultedOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &override ); + + // Verify tester has logged in with DD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + U32 pumpId = override.index; + + // Verify concentrate pump index of override + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + U32 value = override.state.u32; + + concentratePumps[ pumpId ].parkFaulted.ovData = value; + concentratePumps[ pumpId ].parkFaulted.override = OVERRIDE_KEY; + } + else + { + concentratePumps[ pumpId ].parkFaulted.override = OVERRIDE_RESET; + concentratePumps[ pumpId ].parkFaulted.ovData = concentratePumps[ pumpId ].parkFaulted.ovInitData; + } + + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testConcentratePumpParkRequestOverride function overrides the given pump + * to park request. + * @details \b Inputs: concentratePumps + * @details \b Outputs: concentratePumps + * @param pumpId concentrate pump id + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testConcentratePumpParkRequestOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + TEST_OVERRIDE_ARRAY_PAYLOAD_T override; + OVERRIDE_TYPE_T ovType = getOverrideArrayPayloadFromMessage( message, &override ); + + // Verify tester has logged in with DD and override type is valid + if ( ( TRUE == isTestingActivated() ) && ( ovType != OVERRIDE_INVALID ) && ( ovType < NUM_OF_OVERRIDE_TYPES ) ) + { + U32 pumpId = override.index; + + // Verify concentrate pump index of override + if ( pumpId < NUM_OF_CONCENTRATE_PUMPS ) + { + if ( OVERRIDE_OVERRIDE == ovType ) + { + U32 value = override.state.u32; + + concentratePumps[ pumpId ].hasParkBeenRequested.ovData = value; + concentratePumps[ pumpId ].hasParkBeenRequested.override = OVERRIDE_KEY; + + if ( TRUE == concentratePumps[ pumpId ].hasParkBeenRequested.ovData ) + { + // If pump is running, stop it w/ park option + if ( TRUE == concentratePumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + requestConcentratePumpOff( (CONCENTRATE_PUMPS_T)pumpId, TRUE ); + } + // If pump is already stopped, just send park command + else + { + stopConcentratePump( (CONCENTRATE_PUMPS_T)pumpId ); + } + } + } + else + { + concentratePumps[ pumpId ].hasParkBeenRequested.override = OVERRIDE_RESET; + concentratePumps[ pumpId ].hasParkBeenRequested.ovData = concentratePumps[ pumpId ].hasParkBeenRequested.ovInitData; + } + + result = TRUE; + } + } + + return result; +} + +/**@}*/ Index: firmware/App/Controllers/ConcentratePumps.h =================================================================== diff -u --- firmware/App/Controllers/ConcentratePumps.h (revision 0) +++ firmware/App/Controllers/ConcentratePumps.h (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -0,0 +1,98 @@ +/************************************************************************** +* +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file ConcentratePumps.h +* +* @author (last) Vinayakam Mani +* @date (last) 19-Sep-2024 +* +* @author (original) Vinayakam Mani +* @date (original) 19-Sep-2024 +* +***************************************************************************/ + +#ifndef __CONCENTRATE_PUMPS_H__ +#define __CONCENTRATE_PUMPS_H__ + +#include "DDCommon.h" +//#include "NVDataMgmt.h" + +/** + * @defgroup ConcentratePumps ConcentratePumps + * @brief Concentrate pumps monitor and control unit. Monitors and control concentrate pump with an closed loop approach. + * + * @addtogroup ConcentratePumps + * @{ + */ + +// ********** public definitions ********** + +#define CONCENTRATE_PUMP_MAX_SPEED 48.0F ///< Maximum speed for concentrate pump in mL/min + +#define PARK_CONC_PUMPS TRUE ///< For park parameter to requestConcentratePumpOff(). +#define NO_PARK_CONC_PUMPS FALSE ///< For park parameter to requestConcentratePumpOff(). + +/// Enumeration of concentrate pumps. +typedef enum ConcentratePumps +{ + + CONCENTRATEPUMPS_CP1_ACID = 0, ///< Acid concentrate pump + CONCENTRATEPUMPS_FIRST = CONCENTRATEPUMPS_CP1_ACID, ///< First concentrate pump in list + CONCENTRATEPUMPS_CP2_BICARB, ///< Bicarbonate concentrate pump + NUM_OF_CONCENTRATE_PUMPS ///< Number of concentrate pumps +} CONCENTRATE_PUMPS_T; + +/// Concentrate pump data struct. +typedef struct +{ + F32 cp1CurrentSetSpeed; ///< Concentrate pump CP1 current set speed + F32 cp1MeasuredSpeed; ///< Concentrate pump CP1 measured speed + F32 cp2CurrentSetSpeed; ///< Concentrate pump CP2 current set speed + F32 cp2MeasuredSpeed; ///< Concentrate pump CP2 measured speed + U32 cp1State; ///< Concentrate pump CP1 current state + U32 cp2State; ///< Concentrate pump CP2 current state + F32 cp1PulseUS; ///< Concentrate pump CP1 pulse in microseconds + F32 cp2PulseUS; ///< Concentrate pump CP2 pulse in microseconds + F32 cp1TargetSpeed; ///< Concentrate pump CP1 target speed + F32 cp2TargetSpeed; ///< Concentrate pump CP2 target speed + BOOL cp1Parked; ///< Concentrate pump CP1 parked status + BOOL cp2Parked; ///< Concentrate pump CP2 parked status + BOOL cp1ParkFault; ///< Concentrate pump CP1 park fault status + BOOL cp2ParkFault; ///< Concentrate pump CP2 park fault status +} CONCENTRATE_PUMP_DATA_T; + +// ********** public function prototypes ********** + +void initConcentratePump( void ); +void execConcentratePumpMonitor( void ); +void execConcentratePumpController( void ); + +SELF_TEST_STATUS_T execConcenratePumpsSelfTest( void ); + +void requestConcentratePumpOn( CONCENTRATE_PUMPS_T pumpId ); +void requestConcentratePumpOff( CONCENTRATE_PUMPS_T pumpId, BOOL park ); + +void setConcentratePumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId, F32 targetSpeed_ml_min ); +F32 getConcentratePumpTargetFlowMLPM( CONCENTRATE_PUMPS_T pumpId ); +F32 getMeasuredPumpSpeedMLPM( CONCENTRATE_PUMPS_T pumpId ); +F32 getPumpTargetSpeed( CONCENTRATE_PUMPS_T pumpId ); +BOOL getConcPumpParkRequest( CONCENTRATE_PUMPS_T pumpId ); +BOOL getConcPumpIsParked( CONCENTRATE_PUMPS_T pumpId ); +BOOL getConcPumpParkIsFaulted( CONCENTRATE_PUMPS_T pumpId ); +BOOL handleConcentratePumpParkRequest( void ); +BOOL isConcPumpParkInProgress( CONCENTRATE_PUMPS_T pumpId ); + +BOOL testConcentratePumpDataPublishIntervalOverride( MESSAGE_T *message ); +BOOL testConcentratePumpTargetSpeedOverride( MESSAGE_T *message ); +BOOL testConcentratePumpMeasuredSpeedOverride( MESSAGE_T *message ); +BOOL testConcentratePumpParkedOverride( MESSAGE_T *message ); +BOOL testConcentratePumpParkCmdFaultedOverride( MESSAGE_T *message ); +BOOL testConcentratePumpParkRequestOverride( MESSAGE_T *message ); + +/**@}*/ + +#endif Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -re228885d4b066320c69bbec2553b5e7fc62ec2cb -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision e228885d4b066320c69bbec2553b5e7fc62ec2cb) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -113,6 +113,9 @@ SW_FAULT_ID_CONDUCTIVITY_WR_INVALID_EXEC_STATE = 82, SW_FAULT_ID_CONDUCTIVITY_RD_INVALID_EXEC_STATE = 83, SW_FAULT_ID_INVALID_CONDUCTIVITY_SENSOR_ID8 = 84, + SW_FAULT_ID_CONCENTRATE_PUMP_EXEC_INVALID_STATE = 85, + SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID = 86, + NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FpgaDD.c =================================================================== diff -u -r8d390efa9309c8a0f430ba4652528fdbdbb6e2b8 -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 8d390efa9309c8a0f430ba4652528fdbdbb6e2b8) +++ firmware/App/Services/FpgaDD.c (.../FpgaDD.c) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -76,10 +76,10 @@ #define CONCENTRATE_CAP_SWITCH_MASK 0x10 ///< Concentrate cap switch bit mask. #define FPGA_CONC_PUMP_FAULT_BITS 0x03 ///< Concentrate pump fault bits mask. -#define FPGA_CP1_PARKED_BIT 0x04 ///< Concentrate pump 1 parked status bit mask. -#define FPGA_CP2_PARKED_BIT 0x10 ///< Concentrate pump 2 parked status bit mask. -#define FPGA_CP1_PARK_FAULT_BIT 0x08 ///< Concentrate pump 1 park fault status bit mask. -#define FPGA_CP2_PARK_FAULT_BIT 0x20 ///< Concentrate pump 2 park fault status bit mask. +#define FPGA_CPA_PARKED_BIT 0x04 ///< Concentrate pump 1 parked status bit mask. +#define FPGA_CPB_PARKED_BIT 0x10 ///< Concentrate pump 2 parked status bit mask. +#define FPGA_CPA_PARK_FAULT_BIT 0x08 ///< Concentrate pump 1 park fault status bit mask. +#define FPGA_CPB_PARK_FAULT_BIT 0x20 ///< Concentrate pump 2 park fault status bit mask. #define FPGA_CONC_PUMP_PARK_COMMAND 0x80 ///< Park command bit for the concentrate pumps. #define FPGA_THD_CONTROL_COMMAND 0X01 ///< FPGA THd control command. #define FPGA_POWER_OUT_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< FPGA power out timeout in milliseconds. @@ -182,6 +182,9 @@ U08 fpgaValveBCPWMStates; ///< Reg 351. Balancing Chamber Valve PWM states U08 fpgaValveUFStates; ///< Reg 352. Ultrafiltration Valves states U08 fpgaValveUFPWMStates; ///< Reg 353. Ultrafiltration Valves PWM states + U08 fpgaCPACPBFault; ///< Reg 354. Concentrate pump fault register for CPA and CPB + U16 fpgaCPAHallSense; ///< Reg 356. Concentrate pump CPA hall sensor pulse width + U16 fpgaCPBHallSense; ///< Reg 358. Concentrate pump CPB hall sensor pulse width } DD_FPGA_SENSORS_T; typedef struct @@ -521,7 +524,7 @@ /*********************************************************************//** * @brief * The setFPGABicarbSetStepSpeed function sets the step speed period for - * concentrate pump CP2. + * concentrate pump CPB. * @details \b Inputs: none * @details \b Outputs: fpgaActuatorSetPoints.fpgaCPBSpeed * @param stepSpeed The concentrate pump step speed period @@ -1271,6 +1274,109 @@ /*********************************************************************//** * @brief + * The getFPGAConcentratePumpsFault function gets concentrate pumps fault + * reported by FGPA. + * @details \b Inputs: fpgaSensorReadings.fpgaCPACPBFault + * @details \b Outputs: none + * @return Latest concentrate pumps fault value + *************************************************************************/ +U08 getFPGAConcentratePumpsFault( void ) +{ + return fpgaSensorReadings.fpgaCPACPBFault & FPGA_CONC_PUMP_FAULT_BITS; +} + +/*********************************************************************//** + * @brief + * The getFPGAAcidPumpIsParked function gets whether the acid pump is currently + * parked. + * @details \b Inputs: fpgaSensorReadings.fpgaCPACPBFault + * @details \b Outputs: none + * @return TRUE if acid pump is parked, FALSE if not + *************************************************************************/ +BOOL getFPGAAcidPumpIsParked( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCPACPBFault & FPGA_CPA_PARKED_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGABicarbPumpIsParked function gets whether the bicarb pump is currently + * parked. + * @details \b Inputs: fpgaSensorReadings.fpgaCPACPBFault + * @details \b Outputs: none + * @return TRUE if bicarb pump is parked, FALSE if not + *************************************************************************/ +BOOL getFPGABicarbPumpIsParked( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCPACPBFault & FPGA_CPB_PARKED_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAAcidPumpParkFault function gets whether the acid pump park command + * has faulted. + * @details \b Inputs: fpgaSensorReadings.fpgaCPACPBFault + * @details \b Outputs: none + * @return TRUE if acid pump park command faulted, FALSE if not + *************************************************************************/ +BOOL getFPGAAcidPumpParkFault( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCPACPBFault & FPGA_CPA_PARK_FAULT_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGABicarbPumpParkFault function gets whether the bicarb pump park command + * has faulted. + * @details \b Inputs: fpgaSensorReadings.fpgaCPACPBFault + * @details \b Outputs: none + * @return TRUE if bicarb pump park command faulted, FALSE if not + *************************************************************************/ +BOOL getFPGABicarbPumpParkFault( void ) +{ + U08 mask = fpgaSensorReadings.fpgaCPACPBFault & FPGA_CPB_PARK_FAULT_BIT; + BOOL result = ( mask > 0 ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGACPAHallSensePulseWidth function gets concentrate pump CPA + * hall sense pulse width. + * @details \b Inputs: fpgaSensorReadings.fpgaCPAHallSense + * @details \b Outputs: none + * @return concentrate pump CPA hall sense pulse width + *************************************************************************/ +U16 getFPGACPAHallSensePulseWidth( void ) +{ + return fpgaSensorReadings.fpgaCPAHallSense; +} + +/*********************************************************************//** + * @brief + * The getFPGACPBHallSensePulseWidth function gets concentrate pump CPB + * hall sense pulse width. + * @details \b Inputs: fpgaSensorReadings.fpgaCPBHallSense + * @details \b Outputs: none + * @return concentrate pump CPB hall sense pulse width + *************************************************************************/ +U16 getFPGACPBHallSensePulseWidth( void ) +{ + return fpgaSensorReadings.fpgaCPBHallSense; +} + +/*********************************************************************//** + * @brief * The getFPGAValveStates function gets the latest sensed valve states. * See setFPGAValveStates for valve state bit positions. * @details \b Inputs: fpgaSensorReadings.fpgaValveStates Index: firmware/App/Services/FpgaDD.h =================================================================== diff -u -r8d390efa9309c8a0f430ba4652528fdbdbb6e2b8 -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision 8d390efa9309c8a0f430ba4652528fdbdbb6e2b8) +++ firmware/App/Services/FpgaDD.h (.../FpgaDD.h) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -119,14 +119,27 @@ U16 getFPGACD4Temp( void ); U32 getFPGACD4Data( void ); -// Pumps ( Concentrate and Gear pumps ) +// Pumps (Concentrate and Gear pumps ) void setFPGAAcidPumpSetStepSpeed( U16 stepSpeed ); void setFPGABicarbSetStepSpeed( U16 stepSpeed ); +void setFPGAAcidPumpControl( U08 control ); +void setFPGABicarbPumpControl( U08 control ); +void setFPGAAcidPumpParkCmd( void ); +void setFPGABicarbPumpParkCmd( void ); + +U08 getFPGAAcidPumpControlStatus( void ); +U08 getFPGABicarbPumpControlStatus( void ); +U08 getFPGAConcentratePumpsFault( void ); +BOOL getFPGAAcidPumpIsParked( void ); +BOOL getFPGABicarbPumpIsParked( void ); +BOOL getFPGAAcidPumpParkFault( void ); +BOOL getFPGABicarbPumpParkFault( void ); +U16 getFPGACPAHallSensePulseWidth( void ); +U16 getFPGACPBHallSensePulseWidth( void ); + void setFPGADialysateOutPumpSpeed( U16 speed ); void setFPGADialysateOutPumpControl( U08 control ); void setFPGADialysateInPumpControl( U08 control ); -void setFPGAAcidPumpControl( U08 control ); -void setFPGABicarbPumpControl( U08 control ); U08 getFPGADialysateOutPumpControl( void ); U08 getFPGADialysateInPumpControl( void ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -re2e51b0219db0132cebb6f65f3dbd803e1f01e30 -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision e2e51b0219db0132cebb6f65f3dbd803e1f01e30) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -20,6 +20,7 @@ #include "reg_system.h" #include "Conductivity.h" +#include "ConcentratePumps.h" #include "Compatible.h" #include "Messaging.h" #include "OperationModes.h" @@ -90,7 +91,13 @@ MSG_ID_DD_CONDUCTIVITY_SENSOR_TEMPERATURE_OVERRIDE_REQUEST, MSG_ID_DD_CONDUCTIVITY_SENSOR_READ_COUNTER_OVERRIDE_REQUEST, MSG_ID_DD_CONDUCTIVITY_SENSOR_ERROR_COUNTER_OVERRIDE_REQUEST, - MSG_ID_DD_CONDUCTIVITY_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST + MSG_ID_DD_CONDUCTIVITY_SENSOR_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_TARGET_SPEED_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_MEASURED_SPEED_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_PARKED_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_PARK_FAULT_OVERRIDE_REQUEST, + MSG_ID_DD_CONCENTRATE_PUMP_PARK_REQUEST_OVERRIDE_REQUEST }; /// Message handling function table @@ -112,7 +119,13 @@ &testConductivitySensorTemperatureReadingsOverride, &testConductivitySensorReadCounterOverride, &testConductivitySensorErrorCounterOverride, - &testConductivitySensorDataPublishIntervalOverride + &testConductivitySensorDataPublishIntervalOverride, + &testConcentratePumpDataPublishIntervalOverride, + &testConcentratePumpTargetSpeedOverride, + &testConcentratePumpMeasuredSpeedOverride, + &testConcentratePumpParkedOverride, + &testConcentratePumpParkCmdFaultedOverride, + &testConcentratePumpParkRequestOverride }; #define NUM_OF_FUNCTION_HANDLERS (sizeof(MSG_FUNCTION_HANDLERS) / sizeof(MsgFuncPtr)) Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -rd741f651b63edc7695b2be2178c9e5c44aaed1f3 -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision d741f651b63edc7695b2be2178c9e5c44aaed1f3) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -18,6 +18,7 @@ #include "gio.h" #include "lin.h" +#include "ConcentratePumps.h" #include "Messaging.h" #include "OperationModes.h" #include "SystemCommDD.h" @@ -68,7 +69,7 @@ #ifndef BOARD_WITH_NO_HARDWARE // monitor concentrate pumps - //execConcentratePumpMonitor(); + execConcentratePumpMonitor(); // Monitor DG voltages ///execVoltagesMonitor(); @@ -85,7 +86,7 @@ // execDrainPumpController(); // manage concentrate pumps - //execConcentratePumpController(); + execConcentratePumpController(); // Manage switches monitor //execSwitches(); Index: firmware/source/sys_main.c =================================================================== diff -u -r9bd502d3342764c0847258a81a212b446172a8b4 -r3a87ca0e2a722318216623d7e1f4c354c58c506c --- firmware/source/sys_main.c (.../sys_main.c) (revision 9bd502d3342764c0847258a81a212b446172a8b4) +++ firmware/source/sys_main.c (.../sys_main.c) (revision 3a87ca0e2a722318216623d7e1f4c354c58c506c) @@ -63,6 +63,7 @@ #include "AlarmMgmtDD.h" #include "CommBuffers.h" #include "Conductivity.h" +#include "ConcentratePumps.h" #include "DDCommon.h" #include "FpgaDD.h" #include "Interrupts.h" @@ -160,6 +161,7 @@ initPressure(); initConductivity(); initValves(); + initConcentratePump(); initCommBuffers(); initMsgQueues(); initSystemComm();