/**********************************************************************//** * * Copyright (c) 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 Reservoirs.c * * @date 18-Mar-2020 * @author S. Nash * * @brief Reservoirs service module. Maintains reservoir set points and \n * handles reservoir related commands from the HD. * **************************************************************************/ #include // for memcpy() #include "TaskGeneral.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "Reservoirs.h" /** * @addtogroup Reservoirs * @{ */ // ********** private definitions ********** #define MIN_RESERVOIR_VOLUME_ML 0 ///< Minimum reservoir volume in mL. #define MAX_RESERVOIR_VOLUME_ML 3000 ///< Maximum reservoir volume in mL. #define DEFAULT_FILL_VOLUME_ML 1500 ///< Default fill volume for treatment in mL. #define DISINFECT_FILL_VOLUME_ML 2900 ///> Fill volume for disinfection in mL. #define MAX_FILL_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///> Maximum fill volume in mL. #define DEFAULT_DRAIN_VOLUME_ML 100 ///> Default drain volume in mL. #define MAX_DRAIN_VOLUME_ML MAX_RESERVOIR_VOLUME_ML ///> Maximum drain volume in mL. #define MIN_DRAIN_VOLUME_ML 20 ///> Minimum drain volume in mL. #define RESERVOIR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< interval (ms/task time) at which the reservoir data is published on the CAN bus. // ********** private data ********** static U32 reservoirDataPublicationTimerCounter = 0; ///< used to schedule reservoir data publication to CAN bus. static OVERRIDE_U32_T activeReservoir = { 0, 0, 0, 0 }; ///< The active reservoir that the DG is filling/draining/etc. static OVERRIDE_U32_T fillVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir fill volume (in mL). static OVERRIDE_U32_T drainVolumeTargetMl = { 0, 0, 0, 0 }; ///< The target reservoir drain volume (in mL). // ********** private function prototypes ********** /*********************************************************************//** * @brief * The initReservoirs function initializes the Reservoirs module. * @details * Inputs : none * Outputs : Reservoirs module initialized. * @param none * @return none *************************************************************************/ void initReservoirs( void ) { activeReservoir.data = RESERVOIR_1; fillVolumeTargetMl.data = DEFAULT_FILL_VOLUME_ML; drainVolumeTargetMl.data = DEFAULT_DRAIN_VOLUME_ML; } void execReservoirs( void ) { // TODO - publish active reservoir, fill/drain volume targets at 1 Hz. if ( ++reservoirDataPublicationTimerCounter >= RESERVOIR_DATA_PUB_INTERVAL ) { U32 actRes = getActiveReservoir(); U32 filVol = getReservoirFillVolumeTargetMl(); U32 drnVol = getReservoirDrainVolumeTargetMl(); broadcastReservoirData( actRes, filVol, drnVol ); reservoirDataPublicationTimerCounter = 0; } } BOOL setActiveReservoir( RESERVOIR_ID_T resID ) { BOOL result = FALSE; // switch reservoir command only valid in re-circulate mode if ( MODE_CIRC == getCurrentOperationMode() ) { // validate parameters if ( resID < NUM_OF_RESERVOIRS ) { activeReservoir.data = (U32)resID; result = TRUE; } } return result; } /*********************************************************************//** * @brief * The startFill function handles a fill command from the HD. * @details * Inputs : none * Outputs : move to fill mode * @param fillToVolMl : Target volume (in mL) to fill reservoir to. * @return TRUE if fill command successful, FALSE if not. *************************************************************************/ BOOL startFill( U32 fillToVolMl ) { BOOL result = FALSE; // fill command only valid in re-circulate mode if ( MODE_CIRC == getCurrentOperationMode() ) { // validate parameters if ( fillToVolMl < MAX_FILL_VOLUME_ML ) { fillVolumeTargetMl.data = fillToVolMl; requestNewOperationMode( MODE_FILL ); } } return result; } /*********************************************************************//** * @brief * The stopFill function handles a stop fill command from the HD. * @details * Inputs : none * Outputs : move to standby mode * @return TRUE if stop fill command successful, FALSE if not. *************************************************************************/ BOOL stopFill( void ) { BOOL result = FALSE; // stop fill command only valid in fill mode if ( MODE_FILL == getCurrentOperationMode() ) { requestNewOperationMode( MODE_CIRC ); } return result; } /*********************************************************************//** * @brief * The startDrain function handles a fill command from the HD * @details * Inputs : none * Outputs : * @param drainToVolMl : Target volume (in mL) to drain reservoir to. * @return TRUE if drain command successful, FALSE if not. *************************************************************************/ BOOL startDrain( U32 drainToVolMl ) { BOOL result = FALSE; // drain command only valid in re-circulate mode if ( MODE_CIRC == getCurrentOperationMode() ) { // validate parameters if ( ( drainToVolMl > MIN_DRAIN_VOLUME_ML ) && ( drainToVolMl < MAX_DRAIN_VOLUME_ML ) ) { drainVolumeTargetMl.data = drainToVolMl; requestNewOperationMode( MODE_DRAI ); } } return result; } /*********************************************************************//** * @brief * The stopDrain function handles a stop drain command from the HD. * @details * Inputs : none * Outputs : move to standby mode * @return TRUE if stop drain command successful, FALSE if not. *************************************************************************/ BOOL stopDrain( void ) { BOOL result = FALSE; // stop drain command only valid in drain mode if ( MODE_DRAI == getCurrentOperationMode() ) { requestNewOperationMode( MODE_CIRC ); } return result; } /************************************************************************* * GET SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The getActiveReservoir function gets the active reservoir. * @details * Inputs : activeReservoir * Outputs : none * @return the currently active reservoir. *************************************************************************/ RESERVOIR_ID_T getActiveReservoir( void ) { RESERVOIR_ID_T result = (RESERVOIR_ID_T)activeReservoir.data; if ( OVERRIDE_KEY == activeReservoir.override ) { result = (RESERVOIR_ID_T)activeReservoir.ovData; } return result; } /*********************************************************************//** * @brief * The getReservoirFillVolumeTargetMl function gets the reservoir fill \n * volume (in mL). * @details * Inputs : fillVolumeTargetMl * Outputs : none * @return the current target reservoir fill volume (in mL). *************************************************************************/ U32 getReservoirFillVolumeTargetMl( void ) { U32 result = (RESERVOIR_ID_T)fillVolumeTargetMl.data; if ( OVERRIDE_KEY == fillVolumeTargetMl.override ) { result = (RESERVOIR_ID_T)fillVolumeTargetMl.ovData; } return result; } /*********************************************************************//** * @brief * The getReservoirDrainVolumeTargetMl function gets the reservoir drain \n * volume (in mL). * @details * Inputs : drainVolumeTargetMl * Outputs : none * @return the current target reservoir drain volume (in mL). *************************************************************************/ U32 getReservoirDrainVolumeTargetMl( void ) { U32 result = (RESERVOIR_ID_T)drainVolumeTargetMl.data; if ( OVERRIDE_KEY == drainVolumeTargetMl.override ) { result = (RESERVOIR_ID_T)drainVolumeTargetMl.ovData; } return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetDGActiveReservoirOverride function overrides the active \n * reservoir. * @details * Inputs : activeReservoir * Outputs : activeReservoir * @param value : override active reservoir ID. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDGActiveReservoirOverride( RESERVOIR_ID_T value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; activeReservoir.ovData = value; activeReservoir.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The activeReservoir function resets the override of the active \n * reservoir. * @details * Inputs : activeReservoir * Outputs : activeReservoir * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetDGActiveReservoirOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; activeReservoir.override = OVERRIDE_RESET; activeReservoir.ovData = activeReservoir.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetReservoirFillVolumeMlOverride function overrides the target \n * reservoir fill volume (in mL). * @details * Inputs : fillVolumeTargetMl * Outputs : fillVolumeTargetMl * @param value : override target reservoir fill volume (in mL) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetReservoirFillVolumeMlOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; fillVolumeTargetMl.ovData = value; fillVolumeTargetMl.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetReservoirFillVolumeMlOverride function resets the override of the \n * target reservoir fill volume. * @details * Inputs : fillVolumeTargetMl * Outputs : fillVolumeTargetMl * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetReservoirFillVolumeMlOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; fillVolumeTargetMl.override = OVERRIDE_RESET; fillVolumeTargetMl.ovData = fillVolumeTargetMl.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetReservoirDrainVolumeMlOverride function overrides the target \n * reservoir drain volume (in mL). * @details * Inputs : drainVolumeTargetMl * Outputs : drainVolumeTargetMl * @param value : override target reservoir drain volume (in mL) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetReservoirDrainVolumeMlOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; drainVolumeTargetMl.ovData = value; drainVolumeTargetMl.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetReservoirDrainVolumeMlOverride function resets the override of the \n * target reservoir drain volume. * @details * Inputs : drainVolumeTargetMl * Outputs : drainVolumeTargetMl * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetReservoirDrainVolumeMlOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; drainVolumeTargetMl.override = OVERRIDE_RESET; drainVolumeTargetMl.ovData = drainVolumeTargetMl.ovInitData; } return result; } /**@}*/