Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r07e2e63c1d8ff6fd3e967d72f27a60cba07014d1 -ra28daf72bbc8bd7313425471555d5189d946af13 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 07e2e63c1d8ff6fd3e967d72f27a60cba07014d1) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision a28daf72bbc8bd7313425471555d5189d946af13) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2025 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 Valves.c * -* @author (last) Dara Navaei -* @date (last) 16-May-2023 +* @author (last) Sean Nash +* @date (last) 12-Feb-2024 * * @author (original) Dara Navaei * @date (original) 07-Aug-2020 @@ -19,7 +19,6 @@ #include "reg_het.h" #include "gio.h" -#include "Battery.h" #include "CPLD.h" #include "FPGA.h" #include "MessageSupport.h" @@ -83,6 +82,7 @@ #define INITIAL_ENERGIZED_EDGE_UPPER_RANGE 13250U ///< Energized edge maximum count #define INITIAL_ENERGIZED_EDGE_LOWER_RANGE 10750U ///< Energized edge minimum count +#define FIRST_ENERGIZED_EDGE_LOWER_RANGE 9000U ///< Energized edge minimum count on very first home after power up. #define INITIAL_V3_ENERGIZED_EDGE_UPPER_RANGE 14000U ///< Energized edge maximum count #define INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE 10750U ///< Energized edge minimum count @@ -115,6 +115,28 @@ #define DATA_PUBLISH_COUNTER_START_COUNT 80 ///< Data publish counter start count. +#define VALVE_INIT_STATUS_BIT 0x0001 ///< valve init +#define VALVE_ENABLE_PID_STATUS_BIT 0x0002 ///< valve PID enabled +#define VALVE_ENABLE_BYPASS_STATUS_BIT 0x0004 ///< valve bypass + +#define VALVE_PID_CHECK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT ) +#define VALVE_CHECK_MASK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT | VALVE_ENABLE_BYPASS_STATUS_BIT ) +#define VALVE_CHECK_BITS_PER_VALVE ( 3 ) + +#define VDI_POS ( 2 ) +#define VDO_POS ( 3 ) +#define VBA_POS ( 0 ) +#define VBV_POS ( 1 ) +#define VDI_VALVE_CHECK ( VALVE_PID_CHECK << ( VDI_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VDO_VALVE_CHECK ( VALVE_PID_CHECK << ( VDO_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VBA_VALVE_CHECK ( VALVE_PID_CHECK << ( VBA_POS * VALVE_CHECK_BITS_PER_VALVE ) ) +#define VBV_VALVE_CHECK ( VALVE_PID_CHECK << ( VBV_POS * VALVE_CHECK_BITS_PER_VALVE ) ) + +#define VDI_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VDI_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VDO_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VDO_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VBA_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VBA_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) +#define VBV_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VBV_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) + /// Exec valve self test states typedef enum valves_Self_Test_States { @@ -201,25 +223,6 @@ VALVE_BYPASS_T bypassModeStatus; ///< Valve bypass (fixed PWM) mode } VALVE_STATUS_T; -// ********** private data ********** - -static VALVE_SELF_TEST_STATE_T valveSelfTestState; ///< Valves self test state -static SELF_TEST_STATUS_T valvesSelfTestResult; ///< Valves self test result -static VALVE_STATUS_T valvesStatus[ NUM_OF_VALVES ]; ///< Array of type VALVE_STATUS_T structure that holds the status of each valve - -static OVERRIDE_U32_T valvesDataPublishInterval = { VALVES_DATA_PUB_INTERVAL, VALVES_DATA_PUB_INTERVAL, 0, 0 }; ///< Valves data publish interval - -static OVERRIDE_U32_T valvesPositionOverride[ NUM_OF_VALVES ] = { VALVE_POSITION_C_CLOSE, VALVE_POSITION_C_CLOSE, 0, 0 }; ///< Valves position override - -static const U16 VALVE_CONTROL_MODES_SET_BITS[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_MODES ] = - { { VDI_SET_PID_BIT_MASK, VDI_SET_BYPASS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, - { VDO_SET_PID_BIT_MASK, VDO_SET_BYPASS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, - { VBA_SET_PID_BIT_MASK, VBA_SET_BYPASS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, - { VBV_SET_PID_BIT_MASK, VBV_SET_BYPASS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control mode set bits - -static const U16 VALVE_CONTROL_MODES_RESET_BITS[ NUM_OF_VALVES ] = { VDI_RESET_CONTROL_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK, - VBA_RESET_CONTROL_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK }; ///< Valves control modes rest bits - /// Valve check entries enum valve_check_entries { @@ -228,40 +231,39 @@ NUM_OF_VALVE_CHECK_ENTRIES, ///< Number of valve check entries }; -#define VALVE_INIT_STATUS_BIT 0x0001 ///< valve init -#define VALVE_ENABLE_PID_STATUS_BIT 0x0002 ///< valve PID enabled -#define VALVE_ENABLE_BYPASS_STATUS_BIT 0x0004 ///< valve bypass - -#define VALVE_PID_CHECK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT ) -#define VALVE_CHECK_MASK ( VALVE_INIT_STATUS_BIT | VALVE_ENABLE_PID_STATUS_BIT | VALVE_ENABLE_BYPASS_STATUS_BIT ) -#define VALVE_CHECK_BITS_PER_VALVE ( 3 ) - -#define VDI_POS ( 2 ) -#define VDO_POS ( 3 ) -#define VBA_POS ( 0 ) -#define VBV_POS ( 1 ) -#define VDI_VALVE_CHECK ( VALVE_PID_CHECK << ( VDI_POS * VALVE_CHECK_BITS_PER_VALVE ) ) -#define VDO_VALVE_CHECK ( VALVE_PID_CHECK << ( VDO_POS * VALVE_CHECK_BITS_PER_VALVE ) ) -#define VBA_VALVE_CHECK ( VALVE_PID_CHECK << ( VBA_POS * VALVE_CHECK_BITS_PER_VALVE ) ) -#define VBV_VALVE_CHECK ( VALVE_PID_CHECK << ( VBV_POS * VALVE_CHECK_BITS_PER_VALVE ) ) - -#define VDI_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VDI_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) -#define VDO_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VDO_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) -#define VBA_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VBA_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) -#define VBV_VALVE_CHECK_MASK ( ( VALVE_CHECK_MASK << ( VBV_POS * VALVE_CHECK_BITS_PER_VALVE ) ) ) - static const U16 VALVE_CHECK[ NUM_OF_VALVES ][ NUM_OF_VALVE_CHECK_ENTRIES ] = { { VDI_VALVE_CHECK, VDI_VALVE_CHECK_MASK }, { VDO_VALVE_CHECK, VDO_VALVE_CHECK_MASK }, { VBA_VALVE_CHECK, VBA_VALVE_CHECK_MASK }, { VBV_VALVE_CHECK, VBV_VALVE_CHECK_MASK } }; ///< Valve check entries +static const U16 VALVE_CONTROL_MODES_SET_BITS[ NUM_OF_VALVES ][ NUM_OF_VALVE_CONTROL_MODES ] = + { { VDI_SET_PID_BIT_MASK, VDI_SET_BYPASS_BIT_MASK, VDI_RESET_CONTROL_BIT_MASK }, + { VDO_SET_PID_BIT_MASK, VDO_SET_BYPASS_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK }, + { VBA_SET_PID_BIT_MASK, VBA_SET_BYPASS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, + { VBV_SET_PID_BIT_MASK, VBV_SET_BYPASS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control mode set bits +static const U16 VALVE_CONTROL_MODES_RESET_BITS[ NUM_OF_VALVES ] = { VDI_RESET_CONTROL_BIT_MASK, VDO_RESET_CONTROL_BIT_MASK, + VBA_RESET_CONTROL_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK }; ///< Valves control modes rest bits + +// ********** private data ********** + +static VALVE_SELF_TEST_STATE_T valveSelfTestState; ///< Valves self test state +static SELF_TEST_STATUS_T valvesSelfTestResult; ///< Valves self test result +static VALVE_STATUS_T valvesStatus[ NUM_OF_VALVES ]; ///< Array of type VALVE_STATUS_T structure that holds the status of each valve + +static OVERRIDE_U32_T valvesDataPublishInterval = { VALVES_DATA_PUB_INTERVAL, VALVES_DATA_PUB_INTERVAL, 0, 0 }; ///< Valves data publish interval + +static OVERRIDE_U32_T valvesPositionOverride[ NUM_OF_VALVES ] = { VALVE_POSITION_C_CLOSE, VALVE_POSITION_C_CLOSE, 0, 0 }; ///< Valves position override + static U16 valvesControlSetBits; ///< Valves control set bit static OPN_CLS_STATE_T valveAirTrapStatus; ///< Air trap valve status (open/close) static HD_VALVES_CAL_RECORD_T valvesCalibrationRecord; ///< Valves calibration record. +static BOOL hasValveEverBeenHomed[ NUM_OF_VALVES ]; ///< Flags indicating whether the valves have been previously homed. +// ********** private function prototypes ********** + // Self test function prototypes static VALVE_SELF_TEST_STATE_T handleValveSelfTestEnableValves( void ); static VALVE_SELF_TEST_STATE_T handleValveSelfTestConfirmEnable( void ); @@ -273,7 +275,9 @@ static VALVE_STATE_T handleValveStateHomingFindDeenergizedEdge( VALVE_T valve ); static VALVE_STATE_T handleValveStateIdle( VALVE_T valve ); static VALVE_STATE_T handleValveStateInTransition( VALVE_T valve ); +#ifdef DEBUG_ENABLED static VALVE_STATE_T handleValveStateInBypassMode( VALVE_T valve ); +#endif // Private function prototypes static void setValveControlMode( VALVE_T valve, VALVE_MODE_T mode ); @@ -323,6 +327,8 @@ valvesStatus[ valve ].current.ovInitData = 0.0F; valvesStatus[ valve ].current.override = 0; valvesStatus[ valve ].dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + + hasValveEverBeenHomed[ valve ] = FALSE; } // Close air trap valve @@ -759,16 +765,22 @@ S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; S16 deltaPosition = currentPosition - targetPosition; U32 energizedUpperEdge = INITIAL_ENERGIZED_EDGE_UPPER_RANGE; - U32 deenergizedLowerEdge = INITIAL_ENERGIZED_EDGE_LOWER_RANGE; + U32 energizedLowerEdge = INITIAL_ENERGIZED_EDGE_LOWER_RANGE; #ifndef _RELEASE_ if ( HW_CONFIG_BETA == getHardwareConfigStatus() ) { energizedUpperEdge = INITIAL_V3_ENERGIZED_EDGE_UPPER_RANGE; - deenergizedLowerEdge = INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE; + energizedLowerEdge = INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE; } #endif + // If first homing, relax lower range in case cartridge still in place which could interfere with homing. + if ( FALSE == hasValveEverBeenHomed[ valve ] ) + { + energizedLowerEdge = FIRST_ENERGIZED_EDGE_LOWER_RANGE; + } + // Still too far from intermediate target position? Either still more travel to go or stuck at end of travel if ( deltaPosition > MAX_DEVIATION_FROM_TGT_IN_TRAVEL_CNTS ) { @@ -779,7 +791,7 @@ S16 deltaEdges = energizedEdge - currentPosition; // The range from energized to de-energized should be in the specified range - if ( ( deltaEdges <= energizedUpperEdge ) && ( deltaEdges >= deenergizedLowerEdge ) ) + if ( ( deltaEdges <= energizedUpperEdge ) && ( deltaEdges >= energizedLowerEdge ) ) { S16 positionC = currentPosition + INITIAL_EDGE_OFFSET_READ_COUNT; S16 positionB = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ]; @@ -805,6 +817,7 @@ valvesStatus[ valve ].hasTransitionBeenRequested = TRUE; valvesStatus[ valve ].hasHomingBeenRequested = FALSE; valvesStatus[ valve ].numberOfFailedHomings = 0; + hasValveEverBeenHomed[ valve ] = TRUE; // Idle will initiate a transition state = VALVE_STATE_IDLE; @@ -926,7 +939,7 @@ state = VALVE_STATE_IDLE; } // Check if the valve's transition time has timed out - else if ( ( TRUE == didTimeout( valvesStatus[ valve ].transitionStartTime, VALVE_TRANSITION_TIMEOUT_MS ) ) && ( FALSE == isACPowerLost() ) ) + else if ( ( TRUE == didTimeout( valvesStatus[ valve ].transitionStartTime, VALVE_TRANSITION_TIMEOUT_MS ) ) && ( getCPLDACPowerLossDetected() != TRUE ) ) { // Go back to Idle state and set the valve position to not in position because it was not able to get to the target position valvesStatus[ valve ].currentPosition = VALVE_POSITION_NOT_IN_POSITION; @@ -1082,7 +1095,7 @@ position &= DISABLE_VALVE_CURRENT_RELAXATION; // If current relaxation is needed, set the MSB to 1 - if ( enableCurrentRelaxation ) + if ( TRUE == enableCurrentRelaxation ) { position |= ENABLE_VALVE_CURRENT_RELAXATION; } @@ -1188,7 +1201,7 @@ for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) { // Check the valve is in Idle state, otherwise the position should not be checked - if ( ( valvesStatus[ valve ].execState == VALVE_STATE_IDLE ) && ( FALSE == getCPLDACPowerLossDetected() ) ) + if ( ( valvesStatus[ valve ].execState == VALVE_STATE_IDLE ) && ( getCPLDACPowerLossDetected() != TRUE ) ) { U32 maxDeviation = MAX_DEVIATION_FROM_TARGET_IN_COUNTS;