Index: firmware/App/Controllers/SubstitutionPump.c =================================================================== diff -u --- firmware/App/Controllers/SubstitutionPump.c (revision 0) +++ firmware/App/Controllers/SubstitutionPump.c (revision 3b27bc5df10e3eb88dd4a532abd153343cf781ec) @@ -0,0 +1,553 @@ +/************************************************************************** +* +* Copyright (c) 2024-2026 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 SubstitutionPumps.c +* +* @author (last) Jashwant Gantyada +* @date (last) 02-Apr-2026 +* +* @author (original) Vinayakam Mani +* @date (original) 19-Sep-2024 +* +***************************************************************************/ +#include "SubstitutionPump.h" +#include "FpgaDD.h" +#include "MessageSupport.h" +#include "Messaging.h" +#include "OperationModes.h" +#include "PersistentAlarm.h" +#include "TaskGeneral.h" +#include "Utilities.h" + +/** + * @addtogroup SubstitutionPumps + * @{ + */ + +// ********** private definitions ********** +#define SUBSTITUTION_PUMP_DATA_PUBLISH_INTERVAL ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Substitution pump is monitored. +#define SUBSTITUTION_PUMP_CONTROL_INTERVAL ( 100 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Substitution pump is controlled. +#define SUBSTITUTION_PUMP_DATA_PUBLISH_COUNTER_START_COUNT 6 ///< Data publish counter start count. + +#define SUBSTITUTION_PUMP_VOLUME_PER_REV 1.25F ///< Volume output every revolution (mL). +#define SUBSTITUTION_PUMP_ZERO_REVOLUTION_COUNT 0 ///< Revolution count reached to Zero. +#define SUBSTITUTION_PUMP_ZERO_FLOW_RATE 0xFFFFFFFF ///< Pulse width value when zero flow rate or pump is off +#define SUBSTITUTION_PUMP_STEP_PER_REV 200.0F ///< Number of steps for every revolution. +#define SUBSTITUTION_PUMP_MICRO_STEPS_PER_STEP 64.0F ///< Number of micro-steps ( fractions of step) per step. +#define SUBSTITUTION_PUMP_VOLUME_TO_REVOLUTION ( ( 1.0F / SUBSTITUTION_PUMP_VOLUME_PER_REV ) * \ + ( SUBSTITUTION_PUMP_STEP_PER_REV * \ + SUBSTITUTION_PUMP_MICRO_STEPS_PER_STEP ) ) ///< Convert volume in to number of revolutions needed. +#define SUBSTITUTION_PUMP_STEP_PERIOD_RESOLUTION ( 0.50F / ( US_PER_SECOND * SEC_PER_MIN ) ) ///< Convert step period resolution (0.50 us) to minute. + +#define SUBSTITUTION_PUMP_FORWARD_DIR 0x1 ///< Concentrate pump forward direction configuration. +#define SUBSTITUTION_PUMP_REVERSE_DIR 0x0 ///< Concentrate pump reverse direction configuration. +#define SUBSTITUTION_PUMP_CONTROL_EIGHTH_STEP 0x04 ///< Substitution pump control 1/8th step. +#define SUBSTITUTION_PUMP_CONTROL_REVERSE_DIR 0x00 ///< Substitution pump control reverse direction. +#define SUBSTITUTION_PUMP_CONTROL_FORWARD_DIR 0x08 ///< Substitution pump control forward direction. +#define SUBSTITUTION_PUMP_CONTROL_ENABLE 0x00 ///< Substitution pump control enable pump. +#define SUBSTITUTION_PUMP_CONTROL_DISABLE 0x10 ///< Substitution pump control disable pump. +#define SUBSTITUTION_PUMP_CONTROL_NOT_RESET 0x20 ///< Substitution pump control not reset. +#define SUBSTITUTION_PUMP_CONTROL_SLEEP_OFF 0x40 ///< Substitution pump control sleep off. + +#define SUBSTITUTION_PUMP_TRANS_TO_RAMP_SPEED_THRESHOLD_MLPM 10.0F ///< Substitution pump transition to ramp to target speed threshold in mL/min. +#define SUBSTITUTION_PUMP_RAMP_SPEED_INCREMENT 5.0F ///< Speed increase (mL/min) when controlling Substitution pump to target step speed. + + +static const U32 SUBSTITUTION_PUMP_CONTROL_FORWARD = SUBSTITUTION_PUMP_CONTROL_SLEEP_OFF | + SUBSTITUTION_PUMP_CONTROL_NOT_RESET | + SUBSTITUTION_PUMP_CONTROL_ENABLE | + SUBSTITUTION_PUMP_CONTROL_FORWARD_DIR | + SUBSTITUTION_PUMP_CONTROL_EIGHTH_STEP; + +static const U32 SUBSTITUTION_PUMP_CONTROL_STOP = SUBSTITUTION_PUMP_CONTROL_SLEEP_OFF | + SUBSTITUTION_PUMP_CONTROL_NOT_RESET | + SUBSTITUTION_PUMP_CONTROL_DISABLE | + SUBSTITUTION_PUMP_CONTROL_FORWARD_DIR | + SUBSTITUTION_PUMP_CONTROL_EIGHTH_STEP; + + +/// Enumeration of Substitution pump states. +typedef enum SubstituionPumpState +{ + SUBSTITUTION_PUMP_OFF_STATE = 0, ///< Substitution pump off state. + SUBSTITUTION_PUMP_RAMP_TO_TARGET_SPEED_STATE, ///< Substitution pump ramp to target state. + SUBSTITUTION_PUMP_CONTROL_TARGET_SPEED_STATE, ///< Substitution pump on state. + NUM_OF_SUBSTITUTION_PUMP_STATES ///< Number of Substitution pump states. +} SUBSTITUTION_PUMP_STATE_T; + +/// Substitution pump data structure +typedef struct +{ + U32 controlTimerCounter; ///< Timer counter to perform control on Substitution pump. + SUBSTITUTION_PUMP_STATE_T execState; ///< Concentrate pump execute current state. + BOOL hasTurnOnPumpsBeenRequested; ///< Flag indicates a request to turn Substitution pumps on. + F32 currentPumpSpeed; ///< Current controlled Substitution pumps' speed (mL/min). + U32 togglePeriodCount; ///< Converted pump speed (mL/min) to toggle period counts (0.5 uS increment counts per step). + U08 direction; ///< Substitution pump motor direction. + U08 controlSet; ///< Substitution pump control set. (Used in DVT). +} SUBSTITUTION_PUMP_T; + +/// Payload record structure for Substitution pump start/stop request +typedef struct +{ + U32 pumpID; ///< Substitution pump ID + U32 startStop; ///< Substitution pump start:1,stop :0. + F32 speed; ///< Speed in ml/min +} SUB_PUMP_START_STOP_CMD_PAYLOAD_T; + +// ********** private data ********** + +static OVERRIDE_U32_T substitutionPumpDataPublishInterval; ///< Substitution pump data publish interval. +static SUBSTITUTION_PUMP_T substitutionPumps[ NUM_OF_SUB_PUMPS ]; ///< Array of Substitution pumps' data structure. +static OVERRIDE_F32_T pumpTargetSpeed[ NUM_OF_SUB_PUMPS ]; ///< Target concentrate pumps' speed (mL/min). + + +// ********** private function prototypes ********** + +static void stopSubstitutionPump( SUBSTITUTION_PUMPS_T pumpId ); +static SUBSTITUTION_PUMP_STATE_T handleSubstitutionPumpOffState( SUBSTITUTION_PUMPS_T pumpId ); +static SUBSTITUTION_PUMP_STATE_T handleSubstitutionPumpControlTargetSpeedState( SUBSTITUTION_PUMPS_T pumpId ); +static BOOL stepSubstitutionPumpToTargetSpeed( SUBSTITUTION_PUMPS_T pumpId ); +static void checkSubstitutionPumpControlSet( SUBSTITUTION_PUMPS_T pumpId ); +static void publishSubstitutionPumpData( void ); + +/*********************************************************************//** + * @brief + * The initSubstitutionPump function initializes the SubstitutionPumps unit. + * @details \b Inputs: none + * @details \b Outputs: SubstitutionPumps unit variables initialized + * @return none + *************************************************************************/ +void initSubstitutionPump( void ) +{ + SUBSTITUTION_PUMPS_T pumpId; + + for ( pumpId = SUBPUMPS_FIRST; pumpId < NUM_OF_SUB_PUMPS; pumpId++ ) + { + substitutionPumps[ pumpId ].controlTimerCounter = 0; + substitutionPumps[ pumpId ].execState = SUBSTITUTION_PUMP_OFF_STATE; + substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested = FALSE; + substitutionPumps[ pumpId ].direction = SUBSTITUTION_PUMP_FORWARD_DIR; + substitutionPumps[ pumpId ].controlSet = SUBSTITUTION_PUMP_CONTROL_FORWARD_DIR; + } + setFPGAD92PumpRevolutionCount( SUBSTITUTION_PUMP_ZERO_FLOW_RATE ); + setFPGAD92PumpControl( SUBSTITUTION_PUMP_CONTROL_STOP ); + + substitutionPumpDataPublishInterval.data = SUBSTITUTION_PUMP_DATA_PUBLISH_INTERVAL; + substitutionPumpDataPublishInterval.ovInitData = SUBSTITUTION_PUMP_DATA_PUBLISH_INTERVAL; + substitutionPumpDataPublishInterval.ovData = 0; + substitutionPumpDataPublishInterval.override = OVERRIDE_RESET; +} + +/*********************************************************************//** + * @brief + * The execSubstitutionPumpController function executes the substitution 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 execSubstitutionPumpController( void ) +{ + SUBSTITUTION_PUMPS_T pumpId; + + for ( pumpId = SUBPUMPS_FIRST; pumpId < NUM_OF_SUB_PUMPS; pumpId++ ) + { + switch ( substitutionPumps[ pumpId ].execState ) + { + case SUBSTITUTION_PUMP_OFF_STATE: + substitutionPumps[ pumpId ].execState = handleSubstitutionPumpOffState( pumpId ); + break; + + case SUBSTITUTION_PUMP_CONTROL_TARGET_SPEED_STATE: + substitutionPumps[ pumpId ].execState = handleSubstitutionPumpControlTargetSpeedState( pumpId ); + break; + + // 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 ) + substitutionPumps[ pumpId ].execState = SUBSTITUTION_PUMP_OFF_STATE; + break; + } + } +} + +/*********************************************************************//** + * @brief + * The handleSubstitutionPumpOffState function turns on a given substitution + * pumps and switch to on state upon request. + * @details \b Inputs: none + * @details \b Outputs: pump turned on + * @param pumpId ID of the substitution pump + * @return state + *************************************************************************/ +static SUBSTITUTION_PUMP_STATE_T handleSubstitutionPumpOffState( SUBSTITUTION_PUMPS_T pumpId ) +{ + SUBSTITUTION_PUMP_STATE_T state = SUBSTITUTION_PUMP_OFF_STATE; + + + if ( TRUE == substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + U08 controlSet = substitutionPumps[ pumpId ].controlSet; + + setFPGAD92PumpRevolutionCount( SUBSTITUTION_PUMP_ZERO_FLOW_RATE ); + setFPGAD92PumpControl( controlSet ); + state = SUBSTITUTION_PUMP_CONTROL_TARGET_SPEED_STATE; + } + else + { + setFPGAD92PumpRevolutionCount( SUBSTITUTION_PUMP_ZERO_FLOW_RATE ); + setFPGAD92PumpControl( SUBSTITUTION_PUMP_CONTROL_STOP ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleSubstitutionPumpControlTargetSpeedState function turns off given + * substitution pumps switch to off state upon request. While in on state, + * the function controls substitution pumps to a target step speed. + * @details \b Inputs: currentPumpSpeed[] + * @details \b Outputs: control given substitution pumps to target step speed + * @param pumpId ID of the substitution pump + * @return state + *************************************************************************/ +static SUBSTITUTION_PUMP_STATE_T handleSubstitutionPumpControlTargetSpeedState( SUBSTITUTION_PUMPS_T pumpId ) +{ + SUBSTITUTION_PUMP_STATE_T state = SUBSTITUTION_PUMP_CONTROL_TARGET_SPEED_STATE; + F32 targetToCurreSpeedDiffMLPM = fabs( getSubstitutionPumpTargetSpeed( pumpId ) - substitutionPumps[ pumpId ].currentPumpSpeed ); + + if ( ++substitutionPumps[ pumpId ].controlTimerCounter >= SUBSTITUTION_PUMP_CONTROL_INTERVAL ) + { + substitutionPumps[ pumpId ].controlTimerCounter = 0; + stepSubstitutionPumpToTargetSpeed( pumpId ); + } + + if ( targetToCurreSpeedDiffMLPM >= SUBSTITUTION_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 + stepSubstitutionPumpToTargetSpeed( pumpId ); + state = SUBSTITUTION_PUMP_RAMP_TO_TARGET_SPEED_STATE; + } + + //Stop the pump if measured rev count reaches zero + if ( FALSE == substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested ) + { + state = SUBSTITUTION_PUMP_OFF_STATE; + stopSubstitutionPump( pumpId ); + } + + return state; +} + +/*********************************************************************//** + * @brief + * The stopSubstitutionPump function sets the given substitution pump step speed + * to zero and turns off substitution pump. Also parks the pump if requested. + * @details \b Inputs: none + * @details \b Outputs: substitutionPumps + * @param pumpId ID of the substitution pump + * @return none + *************************************************************************/ +static void stopSubstitutionPump( SUBSTITUTION_PUMPS_T pumpId ) +{ + substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested = FALSE; // Just to make sure pump is in Off state. + substitutionPumps[ pumpId ].currentPumpSpeed = 0.0F; // set target rate to zero + + // Disable the motor when stopping, to take next revolution count + // Send zero rate command to stop the pump + setFPGAD92PumpControl( SUBSTITUTION_PUMP_CONTROL_STOP ); + setFPGAD92PumpSetStepSpeed( SUBSTITUTION_PUMP_ZERO_FLOW_RATE ); +} + +/*********************************************************************//** + * @brief + * The stepSubstitutionPumpToTargetSpeed function steps current step speed + * toward target speed for the given concentrate pump,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 stepSubstitutionPumpToTargetSpeed( SUBSTITUTION_PUMPS_T pumpId ) +{ + F32 speedIncrease; + BOOL hasTgtBeenReached = FALSE; + F32 currentToTargetDiff = fabs( getSubstitutionPumpTargetSpeed( pumpId ) - substitutionPumps[ pumpId ].currentPumpSpeed ); + + if ( currentToTargetDiff > NEARLY_ZERO ) + { + if ( currentToTargetDiff > SUBSTITUTION_PUMP_RAMP_SPEED_INCREMENT ) + { + speedIncrease = SUBSTITUTION_PUMP_RAMP_SPEED_INCREMENT; + } + else + { + speedIncrease = currentToTargetDiff; + hasTgtBeenReached = TRUE; + } + + // Subtract current speed when target speed is smaller + if ( getSubstitutionPumpTargetSpeed( pumpId ) < substitutionPumps[ pumpId ].currentPumpSpeed ) + { + speedIncrease *= -1.0F; + } + + substitutionPumps[ pumpId ].currentPumpSpeed += speedIncrease; + + // If the pump's target speed is set to be 0, do not ramp down set it to zero immediately + if ( getSubstitutionPumpTargetSpeed( pumpId ) < NEARLY_ZERO ) + { + substitutionPumps[ pumpId ].currentPumpSpeed = 0.0F; + } + } + + if ( substitutionPumps[ pumpId ].currentPumpSpeed > NEARLY_ZERO ) + { + F32 timePerStep; + F32 stepPeriodCounts; + + timePerStep = SUBSTITUTION_PUMP_VOLUME_PER_REV / ( substitutionPumps[ pumpId ].currentPumpSpeed * SUBSTITUTION_PUMP_STEP_PER_REV ); + stepPeriodCounts = timePerStep / ( SUBSTITUTION_PUMP_STEP_PERIOD_RESOLUTION * SUBSTITUTION_PUMP_MICRO_STEPS_PER_STEP ); + substitutionPumps[ pumpId ].togglePeriodCount = (U32)( stepPeriodCounts + FLOAT_TO_INT_ROUNDUP_OFFSET ); + } + else + { + substitutionPumps[ pumpId ].togglePeriodCount = SUBSTITUTION_PUMP_ZERO_FLOW_RATE; + } + + // Check if the control set bit is set as desired and if not, correct it + checkSubstitutionPumpControlSet( pumpId ); + setFPGAD92PumpSetStepSpeed( substitutionPumps[ pumpId ].togglePeriodCount ); + + return hasTgtBeenReached; +} + +/*********************************************************************//** + * @brief + * The checkSubstitutionPumpControlSet function monitors the status of the + * given substitution pumps control set bit and if they are different from the + * required set bit, they are set again. + * @details \b Inputs: substitutionPumps + * @details \b Outputs: none + * @param pumpId pump id to check its control set bit + * @return none + *************************************************************************/ +static void checkSubstitutionPumpControlSet( SUBSTITUTION_PUMPS_T pumpId ) +{ + U08 controlSetBits = getFPGAD92PumpControlStatus(); + + if ( controlSetBits != substitutionPumps[ pumpId ].controlSet ) + { + setFPGAD92PumpControl( substitutionPumps[ pumpId ].controlSet ); + } +} + +/*********************************************************************//** + * @brief + * The getSubstitutionPumpTargetSpeed function gets the current target speed for the given + * substituion pump. + * @details \b Inputs: pumpTargetSpeed + * @details \b Outputs: none + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId substitution pump id to get the current target speed + * @return the current target speed for the given concentrate pump. + *************************************************************************/ +F32 getSubstitutionPumpTargetSpeed( SUBSTITUTION_PUMPS_T pumpId ) +{ + F32 speed = 0.0F; + + if ( pumpId < NUM_OF_SUB_PUMPS ) + { + speed = getF32OverrideValue( &pumpTargetSpeed[ pumpId ] ); + } + 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 requestSubstitutionPumpOn function requests the module to turn on + * the concentrate pumps. + * @details \b Inputs: none + * @details \b Outputs: concentratePumps[],acidConcentratePumpParkPersistenceClear, + * bicarbConcentratePumpParkPersistenceClear, ufPumpParkPersistenceClear + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId concentrate pump id + * @return none + *************************************************************************/ +void requestSubstitutionPumpOn( SUBSTITUTION_PUMPS_T pumpId ) +{ + if ( pumpId < NUM_OF_SUB_PUMPS ) + { + substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested = TRUE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + +/*********************************************************************//** + * @brief + * The requestSubstitutionPumpOff function requests the module to turn off + * the concentrate pumps. + * @details \b Inputs: none + * @details \b Outputs: concentratePumps[] + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId ID of concentrate pump + * @param park TRUE if pump should be parked, FALSE if not + * @return none + *************************************************************************/ +void requestSubstitutionPumpOff( SUBSTITUTION_PUMPS_T pumpId ) +{ + if ( pumpId < NUM_OF_SUB_PUMPS ) + { + substitutionPumps[ pumpId ].hasTurnOnPumpsBeenRequested = FALSE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + +/*********************************************************************//** + * @brief + * The setSubstitutionPumpTargetSpeed function sets the target step speed based on + * given speed in mL/min to specified concentrate pump. + * @details \b Inputs: none + * @details \b Outputs: concentratePumps[] + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid pump ID is seen. + * @param pumpId pump id to set step speed + * @param targetSpeed_ml_min target speed in mL/min + * @param targetVolume_ml dosing volume to be delivered in ml. + * @return none + *************************************************************************/ +void setSubstitutionPumpTargetSpeed( SUBSTITUTION_PUMPS_T pumpId, F32 targetSpeed_ml_min ) +{ + if ( pumpId < NUM_OF_SUB_PUMPS ) + { + if ( targetSpeed_ml_min >= 0.0 ) + { + substitutionPumps[ pumpId ].direction = SUBSTITUTION_PUMP_FORWARD_DIR; + substitutionPumps[ pumpId ].controlSet = SUBSTITUTION_PUMP_CONTROL_FORWARD; + } + else + { + substitutionPumps[ pumpId ].direction = SUBSTITUTION_PUMP_REVERSE_DIR; + substitutionPumps[ pumpId ].controlSet = SUBSTITUTION_PUMP_CONTROL_FORWARD; + targetSpeed_ml_min *= -1.0; + } + + /* + * If 0.0 <= speed <= 200 set it + * If speed < 0.0 set to 0 + * else speed > 200 set to 200 + */ + pumpTargetSpeed[ pumpId ].data = targetSpeed_ml_min; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_CONCENTRATE_PUMP_INVALID_PUMP_ID, pumpId ); + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testConcentratePumpDataPublishIntervalOverride function overrides the + * concentrate pump data publish interval. + * @details \b Inputs: none + * @details \b Outputs: concentratePumpDataPublishInterval + * @param Override message from Dialin which includes the interval + * (in ms) to override the concentrate pump data broadcast interval to. + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSubstitutionPumpDataPublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = u32BroadcastIntervalOverride( message, &substitutionPumpDataPublishInterval, TASK_GENERAL_INTERVAL ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testConcentratePumpTargetSpeedOverride function overrides the target + * speed value of given concentrate pump id. + * @details \b Inputs: none + * @details \b Outputs: pumpTargetSpeed + * @param message Override message from Dialin which includes an ID of + * the pump to override and the state to override the pump to. + * @return TRUE if override successful, FALSE if not + * @note pump traget speed range should be between 3.0F and 45.0F. + *************************************************************************/ +BOOL testSubstituionPumpTargetSpeedOverride( MESSAGE_T *message ) +{ + BOOL result = f32ArrayOverride( message, &pumpTargetSpeed[ 0 ], NUM_OF_SUB_PUMPS - 1 ); + + return result; +} + +/*********************************************************************//** + * @brief + * The testSubstitutionPumpStartStopOverride function starts a given substituion pump + * at mentioned speed/flowrate ( ml/min) or stops the substituion pump. + * @details \b Inputs: tester logged in + * @details \b Outputs: substituionPumps[] + * @param message set message from Dialin which includes the substituion pump to set + * and the state to set the substituion pump to. + * @return TRUE if set request is successful, FALSE if not + *************************************************************************/ +BOOL testSubstitutionPumpStartStopOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + // Verify tester has logged in with DD + if ( TRUE == isTestingActivated() ) + { + // Verify payload length is valid + if ( sizeof( SUB_PUMP_START_STOP_CMD_PAYLOAD_T ) == message->hdr.payloadLen ) + { + SUB_PUMP_START_STOP_CMD_PAYLOAD_T payload; + + memcpy( &payload, message->payload, sizeof(SUB_PUMP_START_STOP_CMD_PAYLOAD_T) ); + + if ( (SUBSTITUTION_PUMPS_T)payload.pumpID < NUM_OF_SUB_PUMPS ) + { + // Handle start command + if ( TRUE == payload.startStop ) + { + setSubstitutionPumpTargetSpeed( (SUBSTITUTION_PUMPS_T)payload.pumpID, payload.speed ); + requestSubstitutionPumpOn ( (SUBSTITUTION_PUMPS_T)payload.pumpID ); + result = TRUE; + } + + //Handle stop command + if ( FALSE == payload.startStop ) + { + requestSubstitutionPumpOff( (SUBSTITUTION_PUMPS_T)payload.pumpID ); + result = TRUE; + } + } + } + } + + return result; +} + +/**@}*/