Index: firmware/App/Controllers/Valves.c =================================================================== diff -u --- firmware/App/Controllers/Valves.c (revision 0) +++ firmware/App/Controllers/Valves.c (revision 24bf8d1d7a248f907a5c60496a764ae1ef9876f6) @@ -0,0 +1,584 @@ +/************************************************************************** +* +* 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 ValvesDD.c +* +* @author (last) Vinayakam Mani +* @date (last) 14-Aug-2024 +* +* @author (original) Vinayakam Mani +* @date (original) 14-Aug-2024 +* +***************************************************************************/ +#include +#include // For memcpy +#include +#include "MessageSupport.h" +#include "Messaging.h" +#include "TaskPriority.h" +#include "Timers.h" + +/** + * @addtogroup Valves + * @{ + */ + +// ********** private definitions ********** + +#define DEENERGIZED 0 ///< 0 for de-energized valve. +#define ENERGIZED 1 ///< 1 for energized valve. +#define ALL_VALVES_DEENERGIZED 0x0000 ///< 0 in U16 bit field for all valves. + +#define MAX_VALVE_STATE_MISMATCH_TIMER_COUNT (100 / TASK_PRIORITY_INTERVAL ) ///< Maximum time commanded valves state can fail to match read back valve states in a row. + +#define VALVES_STATE_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval ( ms / task time) at which valves states are published on CAN bus. +#define DATA_PUBLISH_COUNTER_START_COUNT 50 ///< Data publish counter start count. + +// ********** private data ********** + +static U32 valvesStatesPublicationTimerCounter; ///< Timer counter used to schedule valve state publication to CAN bus. +static U16 commandedValvesStates = ALL_VALVES_DEENERGIZED; ///< Initialize commanded valves states bit field. +static U08 commandedBCValveStates = ALL_VALVES_DEENERGIZED; ///< Initialize balancing chamber commanded valves states bit field. +static U08 commandedUFValveStates = ALL_VALVES_DEENERGIZED; ///< Initialize ultra filtration commanded valves states bit field. +static U32 valveStateMismatchTimerCounter; ///< Initialize valve state mismatch timer. +static U32 pendingValveStateChanges[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state changes. +static U32 pendingValveStateChangeCountDowns[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state change count down timers (in task intervals). + +static OVERRIDE_U32_T valveStates[ NUM_OF_VALVES ]; ///< Currently commanded valves states. +static OVERRIDE_U32_T valveSensedStates[ NUM_OF_VALVES ]; ///< Valve sensed states override. +static OVERRIDE_U32_T valvesStatesPublishInterval = { VALVES_STATE_PUB_INTERVAL, VALVES_STATE_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. + +// ********** private function prototypes ********** + +static void publishValvesStates( void ); +static void convertU32ArrayToBytes( void ); +static BOOL checkValveStateName( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ); +static U32 convertValveStateNameToValveState( VALVE_STATE_NAMES_T valveStateName ); +static U32 getValveState( U32 valveID ); + +/*********************************************************************//** + * @brief + * The initValves function initializes the Valves module. + * @details \b Inputs: none + * @details \b Outputs: valveStates, pendingValveStateChanges, valveSensedStates, + * pendingValveStateChangeCountDowns, valveStateMismatchCounter, + * commandedValvesStates + * @return none + *************************************************************************/ +void initValves( void ) +{ + U32 i; + + // initialize commanded valve states + for ( i = 0; i < NUM_OF_VALVES; i++ ) + { + valveStates[ i ].data = DEENERGIZED; + valveStates[ i ].ovInitData = DEENERGIZED; + valveStates[ i ].ovData = DEENERGIZED; + valveStates[ i ].override = OVERRIDE_RESET; + pendingValveStateChanges[ i ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ i ] = 0; + valveSensedStates[ i ].data = DEENERGIZED; + valveSensedStates[ i ].ovInitData = DEENERGIZED; + valveSensedStates[ i ].ovData = DEENERGIZED; + valveSensedStates[ i ].override = OVERRIDE_RESET; + } + + // initialize specific to DD module + valveStateMismatchTimerCounter = 0; + valvesStatesPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; // reset valves states publication timer + + convertU32ArrayToBytes(); + // initially set all valves to de-energized state via FPGA + setFPGAValveStates( commandedValvesStates ); + setFPGABCValveStates( commandedBCValveStates ); + setFPGAUFValveStates( commandedUFValveStates ); +} + +/*********************************************************************//** + * @brief + * The execValves function executes the valves driver. + * @details \b Inputs: valvesStates, valveStateMismatchCounter + * pendingValveStateChangeCountDowns, commandedValvesStates, + * commandedBCValveStates , commandedUFValveStates + * @details \b Outputs: valvesStates, valveStateMismatchCounter + * pendingValveStateChanges, valve controls + * @details \b Alarm: ALARM_ID_DD_VALVE_CONTROL_FAILURE when FPGA read back + * valve state mismatches with the commanded valve state after defined time (100ms). + * @return none + *************************************************************************/ +void execValves( void ) +{ + U32 i; + // get valves states from FPGA + U16 readValvesStates = getFPGAValveStates(); + U08 readValveBCStates = getFPGAValveBCStates(); + U08 readValveUFStates = getFPGAValveUFStates(); + + // Verify read back FPGA valve states match last commanded valve states + if ( ( readValvesStates != commandedValvesStates ) || + ( readValveBCStates != commandedBCValveStates ) || + ( readValveUFStates != commandedUFValveStates ) ) + { + valveStateMismatchTimerCounter++; // increment valve state mismatch counter by 1 + if ( valveStateMismatchTimerCounter > MAX_VALVE_STATE_MISMATCH_TIMER_COUNT ) + { + activateAlarmNoData( ALARM_ID_DD_VALVE_CONTROL_FAILURE ); + } + } + else + { + valveStateMismatchTimerCounter = 0; + } + + // Handle pending delayed valve state changes + for ( i = 0; i < NUM_OF_VALVES; i++ ) + { + if ( pendingValveStateChangeCountDowns[ i ] > 0 ) + { + pendingValveStateChangeCountDowns[ i ]--; + if ( 0 == pendingValveStateChangeCountDowns[ i ] ) + { + valveStates[ i ].data = pendingValveStateChanges[ i ]; + pendingValveStateChanges[ i ] = DEENERGIZED; + } + } + } + + // Set valves states (via FPGA) to currently commanded states + convertU32ArrayToBytes(); + setFPGAValveStates( commandedValvesStates ); + setFPGABCValveStates( commandedBCValveStates ); + setFPGAUFValveStates( commandedUFValveStates ); + + // Publish valve states on interval + publishValvesStates(); +} + +/*********************************************************************//** + * @brief + * The convertU32ArrayToBytes function converts an array of U32 valve states + * to U16 and U08 valvesStates that can be passed to FPGA for setting valves. + * @details \b Inputs: valveStates[] + * @details \b Outputs: none + * @return converted U16 and U08 bit field for currently commanded valve states + *************************************************************************/ +static void convertU32ArrayToBytes( void ) +{ + U32 i; + + commandedValvesStates = ALL_VALVES_DEENERGIZED; + commandedBCValveStates = ALL_VALVES_DEENERGIZED; + commandedUFValveStates = ALL_VALVES_DEENERGIZED; + + // flag valves that are currently commanded to be energized + for ( i = 0; i < RSRVD_SPACE1; i++ ) + { + commandedValvesStates |= ( getValveState( i ) == ENERGIZED ? 0x0001 << i : 0 ); + } + + // flag Balancing chamber valves that are currently commanded to be energized + for ( i = BCV1; i <= BCV8; i++ ) + { + commandedBCValveStates |= ( getValveState( i ) == ENERGIZED ? 0x01 << ( i - BCV1 ) : 0 ); + } + + // flag Ultrafiltration valves that are currently commanded to be energized + for ( i = UFI1; i < NUM_OF_VALVES; i++ ) + { + commandedUFValveStates |= ( getValveState( i ) == ENERGIZED ? 0x01 << ( i - UFI1 ) : 0 ); + } +} + +/*********************************************************************//** + * @brief + * The checkValveStateName function checks the validity of requested valve + * state name for given valve. + * @details \b Inputs: none + * @details \b Outputs: none + * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed. + * @param valveID ID of valve to check a valve state name for + * @param valveStateName valve state name to check for given valve ID + * @return TRUE if given valveStateName is appropriate for given valve ID, FALSE if not. + *************************************************************************/ +static BOOL checkValveStateName( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ) +{ + BOOL result = FALSE; // initialize result flag to FALSE + + switch ( valveStateName ) + { + case VALVE_STATE_OPEN: + case VALVE_STATE_CLOSED: + if ( ( VDR == valveID ) || ( VTD == valveID ) || ( VHB == valveID ) || ( VRP == valveID ) || ( VHO == valveID ) || + ( VDB1 == valveID ) || ( VP1 == valveID ) || ( VPT == valveID ) || ( VDB2 == valveID ) || ( VDI == valveID ) || + ( VDO == valveID ) || ( VP2 == valveID ) || ( VHI == valveID ) || ( BCV1 == valveID ) || ( BCV2 == valveID ) || + ( BCV3 == valveID ) || ( BCV4 == valveID ) || ( BCV5 == valveID ) || ( BCV6 == valveID ) || ( BCV7 == valveID ) || + ( BCV8 == valveID ) || ( UFI1 == valveID ) || ( UFO1 == valveID ) || ( UFI2 == valveID ) || ( UFO2 == valveID ) ) + { + result = TRUE; + } + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, valveStateName ) + break; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The convertValveStateNameToValveState function converts valve state \n + * name to its corresponding de-energized (0) or energized (1) valve state. + * @details \b Inputs: none + * @details \b Outputs: none + * @details \b Alarm : ALARM_ID_DD_SOFTWARE_FAULT when invalid valve state name passed + * @param valveStateName valve state name enumeration to convert to energized/de-energized + * @return converted valve state for given valve state name + *************************************************************************/ +static U32 convertValveStateNameToValveState( VALVE_STATE_NAMES_T valveStateName ) +{ + U32 vState = DEENERGIZED; // initialize valve state to de-energized + + switch ( valveStateName ) + { + case VALVE_STATE_OPEN: + vState = ENERGIZED; + break; + + case VALVE_STATE_CLOSED: + vState = DEENERGIZED; + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, valveStateName ) + break; + } + + return vState; +} + +/*********************************************************************//** + * @brief + * The setValveState function sets the valve state for given valve. + * @details \b Inputs: none + * @details \b Outputs: valveStates[], pendingValveStateChanges[], pendingValveStateChangeCountDowns[] + * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed + * @param valveID ID of valve to set state for + * @param valveStateName name of valve state to set given valve to + * @return TRUE if new valve state is set for given valve ID, FALSE if not. + *************************************************************************/ +BOOL setValveState( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName ) +{ + BOOL result = FALSE; // initialize result flag to FALSE + + if ( valveID < NUM_OF_VALVES ) + { + if ( TRUE == checkValveStateName( valveID, valveStateName ) ) + { + valveStates[ valveID ].data = convertValveStateNameToValveState( valveStateName ); + result = TRUE; + // If a delayed state change is pending for this valve, cancel it + pendingValveStateChanges[ valveID ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ valveID ] = 0; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setValveStateDelayed function sets the valve state for given valve + * after a given delay. + * @details \b Inputs: pendingValveStateChangeCountDowns[] + * @details \b Outputs: pendingValveStateChangeCountDowns[], pendingValveStateChangeCountDowns[] + * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed + * @param valveID ID of valve to set state for + * @param valveStateName name of valve state to set given valve to + * @param delayMs delay duration (in ms) before actuation + * @return TRUE if new valve state is set for given valve ID, FALSE if not. + *************************************************************************/ +BOOL setValveStateDelayed( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName, U32 delayMs ) +{ + BOOL result = FALSE; // initialize result flag to FALSE + + if ( valveID < NUM_OF_VALVES ) + { + if ( TRUE == checkValveStateName( valveID, valveStateName ) ) + { + // If a delayed state change is already pending for this valve, execute it now before setting a new delayed state change + if ( pendingValveStateChangeCountDowns[ valveID ] > 0 ) + { + valveStates[ valveID ].data = pendingValveStateChanges[ valveID ]; + } + // Set delayed valve state change + pendingValveStateChanges[ valveID ] = convertValveStateNameToValveState( valveStateName ); + pendingValveStateChangeCountDowns[ valveID ] = delayMs / TASK_PRIORITY_INTERVAL; + result = TRUE; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getValveStateName function gets the current valve state enum for given valve. + * @details \b Inputs: valveStates[] + * @details \b Outputs: none + * @details \b Alarm: ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed. + * @param valveID ID of valve to get state for + * @return the current valve state for given valve in enum + *************************************************************************/ +VALVE_STATE_NAMES_T getValveStateName( VALVES_T valveID ) +{ + // Initialized per CppCheck. + VALVE_STATE_NAMES_T name = NUM_OF_VALVE_STATES; + + if ( valveID < NUM_OF_VALVES ) + { + U32 valveState = getU32OverrideValue( &valveStates[ valveID ] ); + + if ( OVERRIDE_KEY == valveSensedStates[ valveID ].override ) + { + valveState = valveSensedStates[ valveID ].ovData; + } + + name = ( DEENERGIZED == valveState ? VALVE_STATE_CLOSED : VALVE_STATE_OPEN ); + + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return name; +} + +/*********************************************************************//** + * @brief + * The getValveState function gets the current valve state for given valve. + * @details \b Inputs: valveStates[] + * @details \b Outputs: none + * @details \b Alarm : ALARM_ID_DD_SOFTWARE_FAULT when invalid valve ID passed + * @param valveID ID of valve to get state for + * @return the current valve state for given valve + *************************************************************************/ +static U32 getValveState( U32 valveID ) +{ + U32 valveState = DEENERGIZED; + + if ( valveID < NUM_OF_VALVES ) + { + valveState = getU32OverrideValue( &valveStates[ valveID ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return valveState; +} + +/*********************************************************************//** + * @brief + * The publishValvesStates function publishes DG valves states at the set interval. + * @details \b Inputs: valvesStatesPublicationTimerCounter + * @details \b Outputs: valvesStatesPublicationTimerCounter + * @details \b Messages: MSG_ID_DD_VALVES_STATES_DATA to publish FPGA read valve states. + * @return none + *************************************************************************/ +static void publishValvesStates( void ) +{ + // publish valve state on interval + if ( ++valvesStatesPublicationTimerCounter >= getU32OverrideValue( &valvesStatesPublishInterval ) ) + { + DD_VALVES_DATA_T data; + U32 i; + + data.valvesStatus = getFPGAValveStates(); + data.valvesBCStatus = getFPGAValveBCStates(); + data.valvesUFStatus = getFPGAValveUFStates(); + + for ( i = 0; i < NUM_OF_VALVES; i++ ) + { + data.valvesSensedState[ i ] = (U08)getValveStateName( (VALVES_T)i ); + } + + broadcastData( MSG_ID_DD_VALVES_STATES_DATA, COMM_BUFFER_OUT_CAN_DD_BROADCAST, (U08*)&data, sizeof( DD_VALVES_DATA_T ) ); + + valvesStatesPublicationTimerCounter = 0; + } +} + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + +/*********************************************************************//** + * @brief + * The testSetValvesStatesPublishIntervalOverride function overrides the + * valves states publish interval. + * @details \b Inputs: none + * @details \b Outputs: valvesStatesPublishInterval + * @param value override valves states publish interval with (in ms) + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValvesStatesPublishIntervalOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + U32 intvl = value / TASK_PRIORITY_INTERVAL; + + result = TRUE; + valvesStatesPublishInterval.ovData = intvl; + valvesStatesPublishInterval.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetValvesStatesPublishIntervalOverride function resets the override + * of the valves states publish interval. + * @details \b Inputs: none + * @details \b Outputs: valvesStatesPublishInterval + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetValvesStatesPublishIntervalOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + valvesStatesPublishInterval.override = OVERRIDE_RESET; + valvesStatesPublishInterval.ovData = valvesStatesPublishInterval.ovInitData; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValveStateOverride function overrides the value of the + * specified valve with a given value. + * @details \b Inputs: none + * @details \b Outputs: valves[] + * @param valveID ID of valve to override for + * @param value override value for the given valve ID + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValveStateOverride( U32 valveID, U32 value ) +{ + BOOL result = FALSE; + + if ( valveID < NUM_OF_VALVES ) + { + if ( TRUE == isTestingActivated() ) + { + valveStates[ valveID ].ovData = value; + valveStates[ valveID ].override = OVERRIDE_KEY; + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetValveStateOverride function resets the override of the specified valve. + * @details \b Inputs: none + * @details \b Outputs: valves[] + * @param valveID ID of valve to reset override state for + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetValveStateOverride( U32 valveID ) +{ + BOOL result = FALSE; + + if ( valveID < NUM_OF_VALVES ) + { + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + valveStates[ valveID ].override = OVERRIDE_RESET; + valveStates[ valveID ].ovData = valveStates[ valveID ].ovInitData; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetValveSensedStateOverride function overrides the value of the + * specified sensed state with a given value. + * @details \b Inputs: none + * @details \b Outputs: valveSensedStates + * @param valve ID of valve to override for + * @param value override value for the given valve ID + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetValveSensedStateOverride( U32 valve, U32 status ) +{ + BOOL result = FALSE; + + if ( valve < NUM_OF_VALVES ) + { + if ( TRUE == isTestingActivated() ) + { + valveSensedStates[ valve ].ovData = status; + valveSensedStates[ valve ].override = OVERRIDE_KEY; + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetValveSensedStateOverride function resets the override of + * the specified valve's sensed state. + * @details \b Inputs: none + * @details \b Outputs: valveSensedStates + * @param valve ID of valve to reset override state for + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testResetValveSensedStateOverride( U32 valve ) +{ + BOOL result = FALSE; + + if ( valve < NUM_OF_VALVES ) + { + if ( TRUE == isTestingActivated() ) + { + valveSensedStates[ valve ].override = OVERRIDE_RESET; + valveSensedStates[ valve ].ovData = valveSensedStates[ valve ].ovInitData; + result = TRUE; + } + } + + return result; +} + +/**@}*/ Index: firmware/App/Controllers/Valves.h =================================================================== diff -u --- firmware/App/Controllers/Valves.h (revision 0) +++ firmware/App/Controllers/Valves.h (revision 24bf8d1d7a248f907a5c60496a764ae1ef9876f6) @@ -0,0 +1,101 @@ +/************************************************************************** +* +* 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 ValvesDD.h +* +* @author (last) Vinayakam Mani +* @date (last) 14-Aug-2024 +* +* @author (original) Vinayakam Mani +* @date (original) 14-Aug-2024 +* +***************************************************************************/ + +#ifndef __VALVES_DD_H__ +#define __VALVES_DD_H__ + +#include "DDCommon.h" + +/** + * @defgroup Valves Valves + * @brief Valves driver module. Controls valves. + * + * @addtogroup Valves + * @{ + */ +/// Enumeration of valves. +typedef enum Valves +{ + VDR = 0, ///< Valve Drain + VTD, ///< Valve IO direct Inlet + VHB, ///< Valve Hydraulics Bypass + VRP, ///< Valve concentrate Shunt + VHO, ///< Valve Hydraulics Outlet + VDB1, ///< Valve DryBcarb Inlet + VP1, ///< Valve BC Gas Chamber Vent + VPT, ///< Valve Dialysate Sample + VDB2, ///< Valve Dialysate Bypass + VDI, ///< Valve Dialysate Inlet + VDO, ///< Valve Dialysate Outlet + VP2, ///< Valve Balance Air Separation Vent + VHI, ///< Valve Hydraulics Inlet + RSRVD_SPACE1, ///< This space has been reserved + RSRVD_SPACE2, ///< This space has been reserved + RSRVD_SPACE3, ///< This space has been reserved + BCV1, ///< Balancing chamber Valve 1 + BCV2, ///< Balancing chamber Valve 2 + BCV3, ///< Balancing chamber Valve 3 + BCV4, ///< Balancing chamber Valve 4 + BCV5, ///< Balancing chamber Valve 5 + BCV6, ///< Balancing chamber Valve 6 + BCV7, ///< Balancing chamber Valve 7 + BCV8, ///< Balancing chamber Valve 8 + UFI1, ///< Ultrafiltration Valve 1 Inlet + UFI2, ///< Ultrafiltration Valve 2 Inlet + UFO1, ///< Ultrafiltration Valve 1 Outlet + UFO2, ///< Ultrafiltration Valve 2 Outlet + NUM_OF_VALVES ///< Number of valves +} VALVES_T; + +/// Enumeration of available valve state names per valve type (from SA and DG SRS documents). +typedef enum ValveStateNames +{ + VALVE_STATE_OPEN = 0, ///< Open valve state, + VALVE_STATE_CLOSED, ///< Closed valve state, + NUM_OF_VALVE_STATES ///< number of valve states +} VALVE_STATE_NAMES_T; + +#pragma pack(push, 1) +/// Valves publish structure +typedef struct +{ + U16 valvesStatus; ///< 2 way valves status. + U08 valvesBCStatus; ///< Balancing chamber valves status. + U08 valvesUFStatus; ///< Ultrafiltration valves status. + U08 valvesSensedState[ NUM_OF_VALVES ]; ///< DD valves sensed states. +} DD_VALVES_DATA_T; +#pragma pack(pop) + +// ********** public function prototypes ********** + +void initValves( void ); +void execValves( void ); + +BOOL setValveState( VALVES_T valve, VALVE_STATE_NAMES_T valveState ); +BOOL setValveStateDelayed( VALVES_T valve, VALVE_STATE_NAMES_T valveState, U32 delayMs ); +VALVE_STATE_NAMES_T getValveStateName( VALVES_T valveID ); + +BOOL testSetValvesStatesPublishIntervalOverride( U32 value ); +BOOL testResetValvesStatesPublishIntervalOverride( void ); +BOOL testSetValveStateOverride( U32 valve, U32 state ); +BOOL testResetValveStateOverride( U32 valveID ); +BOOL testSetValveSensedStateOverride( U32 valve, U32 status ); +BOOL testResetValveSensedStateOverride( U32 valve ); + +/**@}*/ + +#endif