/**********************************************************************//** * * Copyright (c) 2019-2020 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 DGInterface.c * * @date 08-Apr-2020 * @author S. Nash * * @brief Interfaces with and monitors the DG sub-system. * **************************************************************************/ #include "AlarmMgmt.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "DGInterface.h" /** * @addtogroup DGInterface * @{ */ // ********** private definitions ********** #define START_DG_CMD TRUE ///< . #define STOP_DG_CMD FALSE ///< . #define DRAIN_RESERVOIR_TO_VOLUME_ML 100 ///< Drain reservoir to this volume (in mL) during treatment. #define FILL_RESERVOIR_TO_VOLUME_ML 1500 ///< Fill reservoir to this volume (in mL) during treatment. /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States { TREATMENT_RESERVOIR_MGMT_START_STATE = 0, ///< If DG not already in re-circ mode, try to get it there. TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE, ///< In DG re-circ, wait for lines to flush - then start draining inactive reservoir. TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE, ///< Wait for drain to complete. TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE, ///< Wait to fill inactive reservoir (if appropriate) - then start filling inactive reservoir. TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE, ///< Wait for fill to complete. TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE, ///< Wait for active reservoir to be consumed and switch cmd given - then back to flush DG lines state. NUM_OF_TREATMENT_RESERVOIR_MGMT_STATES ///< Number of treatment reservoir mgmt. states. } TREATMENT_RESERVOIR_MGMT_STATE_T; // ********** private data ********** // DG status static DG_OP_MODE_T dgCurrentOpMode = DG_MODE_INIT; static U32 dgSubMode = 0; static BOOL dgStarted = FALSE; static BOOL dgStartetSet = FALSE; static BOOL dgWaterSampled = FALSE; static BOOL dgWaterSampledSet = FALSE; // state machine states static TREATMENT_RESERVOIR_MGMT_STATE_T currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; ///< Current state of treatment mode reservoir management. // DG sensor data static F32 dgPressures[ NUM_OF_DG_PRESSURE_SENSORS ]; static F32 dgPrimaryTempSet = 0.0; static F32 dgPrimaryTemp = 0.0; static F32 dgTrimmerTempSet = 0.0; static F32 dgTrimmerTemp = 0.0; // DG pumps data static F32 dgROPumpFlowRateMlMin = 0.0; static U32 dgROPumpPressureSetPtPSI = 0; static U32 dgDrainPumpSpeedSetPtRPM = 0; // reservoir data static DG_RESERVOIR_ID_T dgActiveReservoir = DG_RESERVOIR_2; static DG_RESERVOIR_ID_T dgActiveReservoirSet = DG_RESERVOIR_2; static U32 dgReservoirFillVolumeTarget = 0; static U32 dgReservoirFillVolumeTargetSet = 0; static U32 dgReservoirDrainVolumeTarget = 0; static U32 dgReservoirDrainVolumeTargetSet = 0; // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initDGInterface function initializes the DGInterface module. * @details * Inputs : none * Outputs : DGInterface module initialized. * @return none *************************************************************************/ void initDGInterface( void ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; } /*********************************************************************//** * @brief * The execTreatmentReservoirMgmt function executes the state machine for the \n * reservoir management during treatment mode. * @details * Inputs : none * Outputs : DG reservoirs (drains & fills) managed. * @return none *************************************************************************/ void execTreatmentReservoirMgmt( void ) { DG_OP_MODE_T dgOpMode = getDGOpMode(); // TODO - the DG mode & sub-mode come as a pair at interval - they MUST be kept together. U32 dgSubMode = getDGSubMode(); // treatment reservoir mgmt. state machine switch ( currentTrtResMgmtState ) { case TREATMENT_RESERVOIR_MGMT_START_STATE: currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE; break; case TREATMENT_RESERVOIR_MGMT_FLUSH_DG_LINES_STATE: if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) { cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML ); } } else if ( DG_MODE_DRAI == dgOpMode ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE; } else { // TODO - ??? } break; case TREATMENT_RESERVOIR_MGMT_DRAIN_RESERVOIR_STATE: if ( DG_MODE_CIRC == dgOpMode ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE; } break; case TREATMENT_RESERVOIR_MGMT_WAIT_TO_FILL_STATE: // delay fill start if we've paused treatment? if ( getTreatmentState() == TREATMENT_DIALYSIS_STATE ) { if ( DG_MODE_CIRC == dgOpMode ) { if ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == dgSubMode ) { cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML ); } } else { // TODO - ??? } } if ( DG_MODE_FILL == dgOpMode ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE; } break; case TREATMENT_RESERVOIR_MGMT_FILL_RESERVOIR_STATE: if ( DG_MODE_CIRC == dgOpMode ) { currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE; } break; case TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RES_SWITCH_STATE: // reservoir switch during treatment should only occur in this state (i.e. when DG is ready). // state will reset to start when next reservoir switch is commanded. // TODO - should this state machine determine when to give reservoir switch command? Or leave to treatment mode? break; default: // TODO - s/w fault currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; break; } } /*********************************************************************//** * @brief * The getDGOpMode function gets the current DG operating mode. * @details * Inputs : dgCurrentOpMode * Outputs : none * @return Current DG operating mode. *************************************************************************/ DG_OP_MODE_T getDGOpMode( void ) { return dgCurrentOpMode; } /*********************************************************************//** * @brief * The getDGSubMode function gets the current DG operating sub-mode. * @details * Inputs : dgSubMode * Outputs : none * @return Current DG operating sub-mode. *************************************************************************/ U32 getDGSubMode( void ) { return dgSubMode; } /*********************************************************************//** * @brief * The getDGPressure function gets the latest pressure reported by the DG \n * for a given pressure sensor. * @details * Inputs : dgPressures[] * Outputs : none * @param sensorID : pressure sensor we are getting reading for. * @return Latest pressure reading reported by DG for the given sensor. *************************************************************************/ F32 getDGPressure( DG_PRESSURE_SENSORS_T sensorID ) { F32 result = 0.0; if ( sensorID < NUM_OF_DG_PRESSURE_SENSORS ) { result = dgPressures[ sensorID ]; } else { // TODO - s/w fault } return result; } /*********************************************************************//** * @brief * The getDGROPumpPressureSetPt function gets the latest RO pump \n * pressure set point reported by the DG. * @details * Inputs : dgROPumpPressureSetPtPSI * Outputs : none * @return Latest RO pump pressure set point reported by DG. *************************************************************************/ U32 getDGROPumpPressureSetPt( void ) { U32 result = dgROPumpPressureSetPtPSI; return result; } /*********************************************************************//** * @brief * The getDGROPumpFlowRateMlMin function gets the latest RO pump flow \n * rate reported by the DG. * @details * Inputs : dgROPumpFlowRateMlMin * Outputs : none * @return Latest RO pump flow rate reported by DG. *************************************************************************/ F32 getDGROPumpFlowRateMlMin( void ) { F32 result = dgROPumpFlowRateMlMin; return result; } /*********************************************************************//** * @brief * The getDGDrainPumpRPMSetPt function gets the latest drain pump RPM \n * set point reported by the DG. * @details * Inputs : dgDrainPumpSpeedSetPtRPM * Outputs : none * @return Latest drain pump RPM set point reported by DG. *************************************************************************/ U32 getDGDrainPumpRPMSetPt( void ) { U32 result = dgDrainPumpSpeedSetPtRPM; return result; } /*********************************************************************//** * @brief * The setDGOpMode function sets the latest DG operating mode reported by \n * the DG. * @details * Inputs : none * Outputs : dgCurrentOpMode * @param opMode : operating mode reported by DG. * @param subMode : sub-mode (current state) of operating mode reported by DG. * @return none *************************************************************************/ void setDGOpMode( U32 opMode, U32 subMode ) { if ( opMode < NUM_OF_DG_MODES ) { dgCurrentOpMode = (DG_OP_MODE_T)opMode; dgSubMode = subMode; } } /*********************************************************************//** * @brief * The setDGDialysateTemperatures function sets the latest temperature data \n * reported by the DG. * @details * Inputs : none * Outputs : dgPrimaryTemp, dgTrimmerTemp * @param primaryHtrTemp : Primary heater temperature reported by DG. * @param trimmerHtrTemp : Trimmer heater temperature reported by DG. * @return none *************************************************************************/ void setDGDialysateTemperatures( F32 primaryHtrTemp, F32 trimmerHtrTemp ) { dgPrimaryTemp = primaryHtrTemp; dgTrimmerTemp = trimmerHtrTemp; } /*********************************************************************//** * @brief * The setDGReservoirsData function sets the latest reservoir data \n * reported by the DG. * @details * Inputs : none * Outputs : dgActiveReservoir, dgReservoirFillVolumeTarget, dgReservoirDrainVolumeTarget * @param resID : ID of active reservoir. * @param fillVol : Reservoir fill to volume reported by DG. * @param drainVol : Reservoir drain to volume reported by DG. * @return none *************************************************************************/ void setDGReservoirsData( DG_RESERVOIR_ID_T resID, U32 fillVol, U32 drainVol ) { if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoir = resID; dgReservoirFillVolumeTarget = fillVol; dgReservoirDrainVolumeTarget = drainVol; } } /*********************************************************************//** * @brief * The setDGPressures function sets the latest pressures reported by the DG. * @details * Inputs : none * Outputs : dgPressures[] * @param roIn : latest RO pump inlet pressure reported by DG. * @param roOut : latest RO pump outlet pressure reported by DG. * @param drainIn : latest drain pump inlet pressure reported by DG. * @param drainOut : latest drain pump outlet pressure reported by DG. * @return none *************************************************************************/ void setDGPressures( F32 roIn, F32 roOut, F32 drainIn, F32 drainOut ) { dgPressures[ DG_PRESSURE_SENSOR_RO_PUMP_INLET ] = roIn; dgPressures[ DG_PRESSURE_SENSOR_RO_PUMP_OUTLET ] = roOut; dgPressures[ DG_PRESSURE_SENSOR_DRAIN_PUMP_INLET ] = drainIn; dgPressures[ DG_PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ] = drainOut; } /*********************************************************************//** * @brief * The setDGROPumpData function sets the latest RO pump data reported by the DG. * @details * Inputs : none * Outputs : dgROPumpPressureSetPtPSI, dgROPumpFlowRateMlMin * @param presSetPt : latest RO pump pressure set point reported by DG. * @param flowRate : latest RO pump flow rate reported by DG. * @return none *************************************************************************/ void setDGROPumpData( U32 presSetPt, F32 flowRate ) { dgROPumpPressureSetPtPSI = presSetPt; dgROPumpFlowRateMlMin = flowRate; } /*********************************************************************//** * @brief * The setDGDrainPumpData function sets the latest drain pump data reported by the DG. * @details * Inputs : none * Outputs : dgDrainPumpSpeedSetPtRPM * @param rpmSetPt : latest drain pump RPM set point reported by DG. * @return none *************************************************************************/ void setDGDrainPumpData( U32 rpmSetPt ) { dgDrainPumpSpeedSetPtRPM = rpmSetPt; } /*********************************************************************//** * @brief * The cmdSetDGDialysateTargetTemps function sends a target dialysate \n * temperature command message to the DG. * @details * Inputs : none * Outputs : dgPrimaryTempSet, dgTrimmerTempSet * @param primaryHtrTemp : commanded target dialysate temperature for the primary heater. * @param trimmerHtrTemp : commanded target dialysate temperature for the trimmer heater. * @return none *************************************************************************/ void cmdSetDGDialysateTargetTemps( F32 primaryHtrTemp, F32 trimmerHtrTemp ) { dgPrimaryTempSet = primaryHtrTemp; dgTrimmerTempSet = trimmerHtrTemp; sendDialysateTempTargetsToDG( primaryHtrTemp, trimmerHtrTemp ); } /*********************************************************************//** * @brief * The cmdStartDG function sends a start command to the DG. DG will transition \n * from standby to re-circulate mode and start producing warm, pure water. * @details * Inputs : none * Outputs : start DG command sent * @return none *************************************************************************/ void cmdStartDG( void ) { dgStarted = TRUE; sendDGStartStopCommand( START_DG_CMD ); } /*********************************************************************//** * @brief * The cmdStopDG function sends a stop command to the DG. DG will transition \n * from re-circulate mode to standby mode. Pumps and heater go off. * @details * Inputs : none * Outputs : stop DG command sent * @return none *************************************************************************/ void cmdStopDG( void ) { dgStarted = FALSE; sendDGStartStopCommand( STOP_DG_CMD ); } /*********************************************************************//** * @brief * The cmdSetDGActiveReservoir function sends a set active reservoir command \n * message to the DG. * @details * Inputs : none * Outputs : set active reservoir command sent to DG. * @param resID : ID of reservoir to set as active (reservoir for HD to draw from). * @return none *************************************************************************/ void cmdSetDGActiveReservoir( DG_RESERVOIR_ID_T resID ) { if ( resID < NUM_OF_DG_RESERVOIRS ) { dgActiveReservoirSet = resID; sendDGSwitchReservoirCommand( resID ); // reset treatment reservoir mgmt. state machine on reservoir switch currentTrtResMgmtState = TREATMENT_RESERVOIR_MGMT_START_STATE; } else { // TODO - s/w fault } } /*********************************************************************//** * @brief * The cmdStartDGFill function sends a fill command message to the DG. * @details * Inputs : none * Outputs : fill command sent to DG. * @param fillToVolMl : volume (in mL) to fill inactive reservoir to. * @return none *************************************************************************/ void cmdStartDGFill( U32 fillToVolMl ) { dgReservoirFillVolumeTargetSet = fillToVolMl; sendDGFillCommand( fillToVolMl ); } /*********************************************************************//** * @brief * The cmdStartDGDrain function sends a drain command message to the DG. * @details * Inputs : none * Outputs : drain command sent to DG. * @param drainToVolMl : volume (in mL) to drain inactive reservoir to. * @return none *************************************************************************/ void cmdStartDGDrain( U32 drainToVolMl ) { dgReservoirDrainVolumeTargetSet = drainToVolMl; sendDGDrainCommand( drainToVolMl ); } /*********************************************************************//** * @brief * The cmdDGSampleWater function sends a sample water command message to the DG. * @details * Inputs : none * Outputs : sample water command sent to DG. * @return none *************************************************************************/ void cmdDGSampleWater( void ) { dgWaterSampled = TRUE; sendDGSampleWaterCommand(); } /**@}*/