Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -rb3231e63a423fd2d8408c1859e2f58001266a5b5 -r037f0edb0b880130563058c809ba50308f2a63e9 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision b3231e63a423fd2d8408c1859e2f58001266a5b5) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 037f0edb0b880130563058c809ba50308f2a63e9) @@ -14,14 +14,14 @@ * @date (original) 18-Mar-2020 * ***************************************************************************/ - -#include // for memcpy() -#include "LoadCell.h" -#include "ModeRecirculate.h" -#include "OperationModes.h" -#include "Reservoirs.h" -#include "SystemCommMessages.h" +#include // for memcpy() + +#include "LoadCell.h" +#include "ModeRecirculate.h" +#include "OperationModes.h" +#include "Reservoirs.h" +#include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "Valves.h" @@ -50,6 +50,7 @@ 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). /// The reservoirs' associate load cell. @@ -61,11 +62,12 @@ static F32 reservoirLowestWeight[ NUM_OF_DG_RESERVOIRS ] = { MAX_RESERVOIR_WEIGHT, MAX_RESERVOIR_WEIGHT }; static U32 reservoirWeightUnchangeStartTime[ NUM_OF_DG_RESERVOIRS ] = { 0, 0 }; ///< The reservoirs' weight start time when weight stop decreasing. static BOOL tareLoadCellRequest; ///< Flag indicates if load cell tare has been requested by HD. - + // ********** private function prototypes ********** static DG_RESERVOIR_ID_T getActiveReservoir( void ); static U32 getReservoirFillVolumeTargetMl( void ); + static U32 getReservoirDrainVolumeTargetMl( void ); /*********************************************************************//** @@ -118,17 +120,21 @@ cmdResponse.commandID = DG_CMD_SWITCH_RESERVOIR; cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - - // switch reservoir command only valid in re-circulate mode - if ( DG_MODE_CIRC == getCurrentOperationMode() ) - { - switch ( resID ) - { - case DG_RESERVOIR_1: + + // switch reservoir command only valid in re-circulate mode + if ( DG_MODE_CIRC == getCurrentOperationMode() ) + { + switch ( resID ) + { + case DG_RESERVOIR_1: activeReservoir.data = (U32)resID; cmdResponse.rejected = FALSE; setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); +#ifndef V_2_SYSTEM + setValveState( VRD1, VALVE_STATE_CLOSED ); +#else + setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); +#endif setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); break; @@ -137,24 +143,28 @@ activeReservoir.data = (U32)resID; cmdResponse.rejected = FALSE; setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); - setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); +#ifndef V_2_SYSTEM + setValveState( VRD2, VALVE_STATE_CLOSED ); +#else + setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); +#endif setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); break; default: // invalid reservoir given - cmd will be NAK'd w/ false result. - cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; - break; - } + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; + break; + } } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; - } + } sendCommandResponseMsg( &cmdResponse ); -} +} /*********************************************************************//** * @brief @@ -203,145 +213,145 @@ sendCommandResponseMsg( &cmdResponse ); } - -/*********************************************************************//** - * @brief - * The startFillCmd function handles a fill command from the HD. - * @details Inputs: none - * @details Outputs: move to fill mode - * @param fillToVolMl Target volume (in mL) to fill reservoir to - * @return none - *************************************************************************/ -void startFillCmd( U32 fillToVolMl ) -{ + +/*********************************************************************//** + * @brief + * The startFillCmd function handles a fill command from the HD. + * @details Inputs: none + * @details Outputs: move to fill mode + * @param fillToVolMl Target volume (in mL) to fill reservoir to + * @return none + *************************************************************************/ +void startFillCmd( U32 fillToVolMl ) +{ DG_CMD_RESPONSE_T cmdResponse; cmdResponse.commandID = DG_CMD_START_FILL; cmdResponse.rejected = TRUE; - cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - - // fill command only valid in re-circulate mode - if ( ( DG_MODE_CIRC == getCurrentOperationMode() ) && - ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getCurrentRecirculateState() ) ) - { - // validate parameters - if ( fillToVolMl < MAX_FILL_VOLUME_ML ) - { - fillVolumeTargetMl.data = fillToVolMl; - requestNewOperationMode( DG_MODE_FILL ); - cmdResponse.rejected = FALSE; + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; + + // fill command only valid in re-circulate mode + if ( ( DG_MODE_CIRC == getCurrentOperationMode() ) && + ( DG_RECIRCULATE_MODE_STATE_RECIRC_WATER == getCurrentRecirculateState() ) ) + { + // validate parameters + if ( fillToVolMl < MAX_FILL_VOLUME_ML ) + { + fillVolumeTargetMl.data = fillToVolMl; + requestNewOperationMode( DG_MODE_FILL ); + cmdResponse.rejected = FALSE; } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; - } + } } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; - } + } - sendCommandResponseMsg( &cmdResponse ); -} - -/*********************************************************************//** - * @brief - * The stopFillCmd function handles a stop fill command from the HD. - * @details Inputs: none - * @details Outputs: move to re-circulate mode - * @return none - *************************************************************************/ -void stopFillCmd( void ) -{ + sendCommandResponseMsg( &cmdResponse ); +} + +/*********************************************************************//** + * @brief + * The stopFillCmd function handles a stop fill command from the HD. + * @details Inputs: none + * @details Outputs: move to re-circulate mode + * @return none + *************************************************************************/ +void stopFillCmd( void ) +{ DG_CMD_RESPONSE_T cmdResponse; cmdResponse.commandID = DG_CMD_STOP_FILL; cmdResponse.rejected = TRUE; cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - - // stop fill command only valid in fill mode - if ( DG_MODE_FILL == getCurrentOperationMode() ) - { - fillVolumeTargetMl.data = 0; - requestNewOperationMode( DG_MODE_CIRC ); - cmdResponse.rejected = FALSE; + + // stop fill command only valid in fill mode + if ( DG_MODE_FILL == getCurrentOperationMode() ) + { + fillVolumeTargetMl.data = 0; + requestNewOperationMode( DG_MODE_CIRC ); + cmdResponse.rejected = FALSE; } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; - } - - sendCommandResponseMsg( &cmdResponse ); -} - -/*********************************************************************//** - * @brief - * The startDrainCmd function handles a drain command from the HD. - * @details Inputs: none - * @details Outputs: Start draining in re-circulate mode - * @param drainCmd drain command data record - * @return none - *************************************************************************/ -void startDrainCmd( DRAIN_CMD_T drainCmd ) -{ + } + + sendCommandResponseMsg( &cmdResponse ); +} + +/*********************************************************************//** + * @brief + * The startDrainCmd function handles a drain command from the HD. + * @details Inputs: none + * @details Outputs: Start draining in re-circulate mode + * @param drainCmd drain command data record + * @return none + *************************************************************************/ +void startDrainCmd( DRAIN_CMD_T drainCmd ) +{ DG_CMD_RESPONSE_T cmdResponse; cmdResponse.commandID = DG_CMD_START_DRAIN; cmdResponse.rejected = TRUE; - cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - - // drain command only valid in re-circulate mode - if ( DG_MODE_CIRC == getCurrentOperationMode() ) - { - // validate parameters - if ( drainCmd.targetVolume <= MAX_DRAIN_VOLUME_ML ) - { + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; + + // drain command only valid in re-circulate mode + if ( DG_MODE_CIRC == getCurrentOperationMode() ) + { + // validate parameters + if ( drainCmd.targetVolume <= MAX_DRAIN_VOLUME_ML ) + { drainVolumeTargetMl.data = drainCmd.targetVolume; - tareLoadCellRequest = drainCmd.tareLoadCell; - requestNewOperationMode( DG_MODE_DRAI ); - cmdResponse.rejected = FALSE; + tareLoadCellRequest = drainCmd.tareLoadCell; + requestNewOperationMode( DG_MODE_DRAI ); + cmdResponse.rejected = FALSE; } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_PARAMETER; - } + } } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; - } - - sendCommandResponseMsg( &cmdResponse ); -} - -/*********************************************************************//** - * @brief - * The stopDrainCmd function handles a stop drain command from the HD. - * @details Inputs: none - * @details Outputs: move to re-circulate mode - * @return none - *************************************************************************/ -void stopDrainCmd( void ) -{ + } + + sendCommandResponseMsg( &cmdResponse ); +} + +/*********************************************************************//** + * @brief + * The stopDrainCmd function handles a stop drain command from the HD. + * @details Inputs: none + * @details Outputs: move to re-circulate mode + * @return none + *************************************************************************/ +void stopDrainCmd( void ) +{ DG_CMD_RESPONSE_T cmdResponse; cmdResponse.commandID = DG_CMD_STOP_DRAIN; cmdResponse.rejected = TRUE; - cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; - - // stop drain command only valid in drain mode - if ( DG_MODE_DRAI == getCurrentOperationMode() ) - { - drainVolumeTargetMl.data = 0; - requestNewOperationMode( DG_MODE_CIRC ); - cmdResponse.rejected = FALSE; - } + cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_NONE; + + // stop drain command only valid in drain mode + if ( DG_MODE_DRAI == getCurrentOperationMode() ) + { + drainVolumeTargetMl.data = 0; + requestNewOperationMode( DG_MODE_CIRC ); + cmdResponse.rejected = FALSE; + } else { cmdResponse.rejectCode = DG_CMD_REQUEST_REJECT_REASON_INVALID_MODE; } - - sendCommandResponseMsg( &cmdResponse ); + + sendCommandResponseMsg( &cmdResponse ); } /*********************************************************************//** @@ -435,20 +445,7 @@ { BOOL result = FALSE; - F32 loadcellWeight = 0.0; - - // TODO remove this code once the load cell is repaired - if ( DG_RESERVOIR_1 == reservoirId ) - { - loadcellWeight = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ); - } - else - { - loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); - } - // TODO remove the above code the load cell is repaired - - //F32 const loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + F32 const loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); U32 const targetDrainVolume = getReservoirDrainVolumeTargetMl(); if ( loadcellWeight < reservoirLowestWeight[ reservoirId ] ) @@ -460,12 +457,15 @@ BOOL const hasTimeOut = didTimeout( reservoirWeightUnchangeStartTime[ reservoirId ], timeout ); BOOL const hasTargetReached = ( targetDrainVolume >= loadcellWeight ); - if ( hasTimeOut || hasTargetReached ) + // If the goal is to tare the load cell, then the target drain should be reached and timing out on the + // reservoir weight is not enough + if ( ( TRUE == hasTimeOut ) || ( ( TRUE == hasTargetReached ) && ( FALSE == tareLoadCellRequest ) ) ) { result = TRUE; + // Reset for next drain reservoirLowestWeight[ reservoirId ] = MAX_RESERVOIR_WEIGHT; - if ( tareLoadCellRequest ) + if ( TRUE == tareLoadCellRequest ) { tareLoadCellRequest = FALSE; tareLoadCell( associatedLoadCell[ reservoirId ] ); @@ -478,6 +478,38 @@ /*********************************************************************//** * @brief + * The tareLoadCellsAtEmpty function tares the load cells for the given + * reservoir when empty and tare request is pending. + * @details Inputs: tareLoadCellRequest + * @details Outputs: tareLoadCellRequest + * @param reservoirId ID of reservoir to tare + * @return none + *************************************************************************/ +void tareLoadCellsAtEmpty( DG_RESERVOIR_ID_T reservoirId ) +{ + if ( TRUE == tareLoadCellRequest ) + { + tareLoadCellRequest = FALSE; + tareLoadCell( associatedLoadCell[ reservoirId ] ); + tareLoadCell( redundantLoadCell[ reservoirId ] ); + } +} + +/*********************************************************************//** + * @brief + * The isReservoirTarePending function determines whether a reservoir tare + * request is currently pending. + * @details Inputs: tareLoadCellRequest + * @details Outputs: none + * @return tareLoadCellRequest + *************************************************************************/ +BOOL isReservoirTarePending( void ) +{ + return tareLoadCellRequest; +} + +/*********************************************************************//** + * @brief * The getActiveReservoir function gets the active reservoir. * @details Inputs: activeReservoir * @details Outputs: none @@ -534,142 +566,142 @@ } -/************************************************************************* - * TEST SUPPORT FUNCTIONS - *************************************************************************/ +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ - -/*********************************************************************//** - * @brief - * The testSetDGActiveReservoirOverride function overrides the active reservoir. - * @details Inputs: activeReservoir - * @details Outputs: activeReservoir - * @param value override active reservoir ID - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetDGActiveReservoirOverride( DG_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 reservoir. - * @details Inputs: activeReservoir - * @details 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 - * reservoir fill volume (in mL). - * @details Inputs: fillVolumeTargetMl - * @details 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 + +/*********************************************************************//** + * @brief + * The testSetDGActiveReservoirOverride function overrides the active reservoir. + * @details Inputs: activeReservoir + * @details Outputs: activeReservoir + * @param value override active reservoir ID + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDGActiveReservoirOverride( DG_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 reservoir. + * @details Inputs: activeReservoir + * @details 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 + * reservoir fill volume (in mL). + * @details Inputs: fillVolumeTargetMl + * @details 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 target reservoir fill volume. - * @details Inputs: fillVolumeTargetMl - * @details 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 - * reservoir drain volume (in mL). - * @details Inputs: drainVolumeTargetMl - * @details 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 target reservoir fill volume. + * @details Inputs: fillVolumeTargetMl + * @details 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 + * reservoir drain volume (in mL). + * @details Inputs: drainVolumeTargetMl + * @details 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 target reservoir drain volume. - * @details Inputs: drainVolumeTargetMl - * @details 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; -} - -/**@}*/ + * the target reservoir drain volume. + * @details Inputs: drainVolumeTargetMl + * @details 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; +} + +/**@}*/