Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -rc9b434898a8bbe9143b243627ea081e5e0f7a861 -r8eb118992bbb2f40666c68be20de57c5eb34b5dc --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision c9b434898a8bbe9143b243627ea081e5e0f7a861) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 8eb118992bbb2f40666c68be20de57c5eb34b5dc) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2023 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) 26-May-2022 +* @date (last) 18-Jan-2023 * * @author (original) Dara Navaei * @date (original) 07-Aug-2020 @@ -79,15 +79,18 @@ #define INITIAL_EDGE_OFFSET_READ_COUNT 100U ///< Offset in counts from energized and de-energized edges -#define INITIAL_ENERGIZED_EDGE_UPPER_RANGE 14000U // TODO it was originally 13000 ///< Energized edge maximum count -#define INITIAL_ENERGIZED_EDGE_LOWER_RANGE 9000U ///< Energized edge minimum count +#define INITIAL_ENERGIZED_EDGE_UPPER_RANGE 13250U ///< Energized edge maximum count +#define INITIAL_ENERGIZED_EDGE_LOWER_RANGE 10750U ///< Energized edge minimum count +#define INITIAL_V3_ENERGIZED_EDGE_UPPER_RANGE 14000U ///< Energized edge maximum count +#define INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE 10750U ///< Energized edge minimum count #define AIR_TRAP_VALVE_GPIO_PIN 0x12 ///< Air trap valve GPIO Pin 18 of HET Port 1 #define HOMING_STEP_CHANGE_IN_COUNTS 1000 ///< Step change in counts during homing #define TRANSITION_STEP_CHANGE_IN_COUNTS 15000 ///< Step change in counts during normal operations -#define MAX_DEVIATION_FROM_TARGET_IN_COUNTS 150 ///< Maximum deviation from target in counts +#define MAX_DEVIATION_FROM_TARGET_IN_COUNTS 1000 ///< Maximum deviation from target in counts +#define MAX_DEVIATION_FROM_TGT_IN_TRAVEL_CNTS 150 ///< Maximum deviation from target in counts #define MAX_DEVIATION_FROM_TRAGET_IN_POS_B 1000 ///< Maximum allowed deviation from position B in counts #define MAX_ALLOWED_FAILED_HOMINGS 3U ///< Maximum allowed failed homings /// The time that the valve must be at the edge to be considered for edge detection @@ -198,12 +201,10 @@ // ********** private data ********** -static VALVE_SELF_TEST_STATE_T valveSelfTestState = VALVE_SELF_TEST_ENABLE_VALVES; ///< Valves self test state -static SELF_TEST_STATUS_T valvesSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Valves self test result +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 -/// Array of type VALVE_STATUS_T structure that holds the status of each valve -static VALVE_STATUS_T valvesStatus[ NUM_OF_VALVES ]; - 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 @@ -223,16 +224,10 @@ { VBA_INIT_STATUS_BIT_MASK, VBA_ENABLE_PID_STATUS_BIT_MASK, VBA_ENABLE_BYPASS_STATUS_BIT_MASK, VBA_RESET_CONTROL_BIT_MASK }, { VBV_INIT_STATUS_BIT_MASK, VBV_ENABLE_PID_STATUS_BIT_MASK, VBV_ENABLE_BYPASS_STATUS_BIT_MASK, VBV_RESET_CONTROL_BIT_MASK } }; ///< Valves control status bits -static U16 valvesControlSetBits = 0x0000; ///< Valves control set bit +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. -// TODO remove for testing only -static S32 testPos[ NUM_OF_VALVES ][300]; -static F32 testCurr[ NUM_OF_VALVES ][ 300 ]; -static U32 idx[ NUM_OF_VALVES ] = {0,0,0,0}; -// TODO remove for testing only - // Self test function prototypes static VALVE_SELF_TEST_STATE_T handleValveSelfTestEnableValves( void ); static VALVE_SELF_TEST_STATE_T handleValveSelfTestConfirmEnable( void ); @@ -273,6 +268,7 @@ void initValves( void ) { VALVE_T valve; + valveSelfTestState = VALVE_SELF_TEST_ENABLE_VALVES; valvesSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; valveAirTrapStatus = STATE_CLOSED; @@ -287,9 +283,9 @@ for ( valve = VDI; valve < NUM_OF_VALVES; valve++ ) { valvesStatus[ valve ].execState = VALVE_STATE_WAIT_FOR_POST; - valvesStatus[ valve ].current.data = 0.0; - valvesStatus[ valve ].current.ovData = 0.0; - valvesStatus[ valve ].current.ovInitData = 0.0; + valvesStatus[ valve ].current.data = 0.0F; + valvesStatus[ valve ].current.ovData = 0.0F; + valvesStatus[ valve ].current.ovInitData = 0.0F; valvesStatus[ valve ].current.override = 0; valvesStatus[ valve ].dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; } @@ -300,11 +296,11 @@ /*********************************************************************//** * @brief - * The homeValve function sets the homing request flag of a valve to TRUE. - * @details Inputs: none - * @details Outputs: valvesStatus (The flag that sets the homing request) + * The homeValve function processes the homing of a valve + * @details Inputs: valvesStatus + * @details Outputs: valvesStatus * @param valve that is set to be homed - * @return none + * @return TRUE if the homing command accepted otherwise, FALSE *************************************************************************/ BOOL homeValve( VALVE_T valve ) { @@ -482,6 +478,19 @@ /*********************************************************************//** * @brief + * The resetValvesPOSTState function resets the valves POST state; + * @details Inputs: none + * @details Outputs: valveSelfTestState, valvesSelfTestResult + * @return none + *************************************************************************/ +void resetValvesPOSTState( void ) +{ + valveSelfTestState = VALVE_SELF_TEST_ENABLE_VALVES; + valvesSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; +} + +/*********************************************************************//** + * @brief * The execValves function executes the valves exec state machine. * @details Inputs: valvesStatus * @details Outputs: valvesStatus @@ -669,7 +678,7 @@ S16 deltaPosition = targetPosition - currentPosition; // If there has not been any major travel for a certain period of time - if ( deltaPosition > MAX_DEVIATION_FROM_TARGET_IN_COUNTS ) + if ( deltaPosition > MAX_DEVIATION_FROM_TGT_IN_TRAVEL_CNTS ) { if ( valvesStatus[ valve ].homingEdgeDetectionCounter >= HOMING_EDGE_DETECTION_TIME_INTERVAL ) { @@ -708,26 +717,35 @@ *************************************************************************/ static VALVE_STATE_T handleValveStateHomingFindDeenergizedEdge( VALVE_T valve ) { - VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; + VALVE_STATE_T state = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; + S16 currentPosition = getValvePositionCounts( valve ); + S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; + S16 deltaPosition = currentPosition - targetPosition; + U32 energizedUpperEdge = INITIAL_ENERGIZED_EDGE_UPPER_RANGE; + U32 deenergizedLowerEdge = INITIAL_ENERGIZED_EDGE_LOWER_RANGE; - S16 currentPosition = getValvePositionCounts( valve ); - S16 targetPosition = valvesStatus[ valve ].targetPositionInCounts; - S16 deltaPosition = currentPosition - targetPosition; +#ifndef _RELEASE_ + if ( HW_CONFIG_BETA == getHardwareConfigStatus() ) + { + energizedUpperEdge = INITIAL_V3_ENERGIZED_EDGE_UPPER_RANGE; + deenergizedLowerEdge = INITIAL_V3_ENERGIZED_EDGE_LOWER_RANGE; + } +#endif // Still too far from intermediate target position? Either still more travel to go or stuck at end of travel - if ( deltaPosition > MAX_DEVIATION_FROM_TARGET_IN_COUNTS ) + if ( deltaPosition > MAX_DEVIATION_FROM_TGT_IN_TRAVEL_CNTS ) { // Are we stuck at end of travel? if ( valvesStatus[ valve ].homingEdgeDetectionCounter >= HOMING_EDGE_DETECTION_TIME_INTERVAL ) { S16 energizedEdge = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ]; S16 deltaEdges = energizedEdge - currentPosition; - // The range from energized to de-energized should be in between 9000 to 13000 steps - if ( deltaEdges <= INITIAL_ENERGIZED_EDGE_UPPER_RANGE && deltaEdges >= INITIAL_ENERGIZED_EDGE_LOWER_RANGE ) + // The range from energized to de-energized should be in the specified range + if ( ( deltaEdges <= energizedUpperEdge ) && ( deltaEdges >= deenergizedLowerEdge ) ) { S16 positionC = currentPosition + INITIAL_EDGE_OFFSET_READ_COUNT; - S16 positionB = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ] - INITIAL_EDGE_OFFSET_READ_COUNT; + S16 positionB = valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ]; // Positions B and C will have an offset from the edge to make sure each time the valve will not hit the edge valvesStatus[ valve ].positions[ VALVE_POSITION_B_OPEN ] = positionB; @@ -843,8 +861,7 @@ *************************************************************************/ static VALVE_STATE_T handleValveStateInTransition( VALVE_T valve ) { - VALVE_STATE_T state = VALVE_STATE_IN_TRANSITION; - + VALVE_STATE_T state = VALVE_STATE_IN_TRANSITION; VALVE_POSITION_T commandedPositionEnum = valvesStatus[ valve ].commandedPosition; // Get the corresponding counts of the positions @@ -863,7 +880,7 @@ if ( commandedPositionEnum == VALVE_POSITION_B_OPEN ) { // Enable current relaxation - setFPGAValveSetPoint( valve, currentPosition, TRUE ); + setFPGAValveSetPoint( valve, targetPosition, TRUE ); } // Go back to Idle state @@ -883,7 +900,7 @@ } } // Check if the valve is close to the temporary target position and if it is, assign the next target position - else if ( abs( currentPosition - targetPosition ) < MAX_DEVIATION_FROM_TARGET_IN_COUNTS ) + else if ( abs( currentPosition - targetPosition ) < MAX_DEVIATION_FROM_TGT_IN_TRAVEL_CNTS ) { setValveNextStep( valve, TRANSITION_STEP_CHANGE_IN_COUNTS ); } @@ -1163,25 +1180,11 @@ valvesStatus[ VBA ].currentPositionInCounts.data = (S32)getFPGAValveBloodArterialPosition(); valvesStatus[ VBV ].currentPositionInCounts.data = (S32)getFPGAValveBloodVenousPosition(); - testPos[VDI][ idx[VDI] ] = valvesStatus[ VDI ].currentPositionInCounts.data; - testCurr[VDI][ idx[VDI] ] = valvesStatus[ VDI ].current.data; - idx[VDI] = INC_WRAP(idx[VDI], 0, 300); - - testPos[VDO][ idx[VDO] ] = valvesStatus[ VDO ].currentPositionInCounts.data; - idx[VDO] = INC_WRAP(idx[VDO], 0, 300); - - testPos[VBA][ idx[VBA] ] = valvesStatus[ VBA ].currentPositionInCounts.data; - idx[VBA] = INC_WRAP(idx[VBA], 0, 300); - - testPos[VBV][ idx[VBV] ] = valvesStatus[ VBV ].currentPositionInCounts.data; - testCurr[VBV][ idx[VBV] ] = valvesStatus[ VBV ].current.data; - idx[VBV] = INC_WRAP(idx[VBV], 0, 300); - // Check the position of each valve 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 ) + if ( ( valvesStatus[ valve ].execState == VALVE_STATE_IDLE ) && ( FALSE == isAlarmActive( ALARM_ID_HD_AC_POWER_LOST ) ) ) { U32 maxDeviation = MAX_DEVIATION_FROM_TARGET_IN_COUNTS; @@ -1205,14 +1208,22 @@ if ( valvesStatus[ valve ].positionOutOfRangeCounter > MAX_POS_DEVIATION_TIME_INTERVAL_COUNTER ) { + // If the valve's deviation from target was more than the counts for the define period of time trigger the alarm. + // Also, set the state to Idle so in the fault mode, the valve can transition to Pos C. The exec state is directly set here + // because this is a monitor function that is called in the controller function. + valvesStatus[ valve ].execState = VALVE_STATE_IDLE; SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_VALVE_POSITION_OUT_OF_RANGE, (U32)valve, currentPosition ); } - else if ( abs( currentPosition - commandedPosition ) < MAX_DEVIATION_FROM_TARGET_IN_COUNTS && - valvesStatus[ valve ].positionOutOfRangeCounter > 0 ) + else if ( ( abs( currentPosition - commandedPosition ) < MAX_DEVIATION_FROM_TARGET_IN_COUNTS ) && + ( valvesStatus[ valve ].positionOutOfRangeCounter > 0 ) ) { valvesStatus[ valve ].positionOutOfRangeCounter = 0; } } + else + { + valvesStatus[ valve ].positionOutOfRangeCounter = 0; + } } } @@ -1290,22 +1301,22 @@ // Subtract the defined number of steps for the next transition if ( commandedPositionEnum == VALVE_POSITION_B_OPEN ) { - valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; + valvesStatus[ valve ].targetPositionInCounts = currentPosition + nextStep; } if ( commandedPositionEnum == VALVE_POSITION_C_CLOSE ) { - valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; + valvesStatus[ valve ].targetPositionInCounts = currentPosition - nextStep; } break; case VALVE_POSITION_B_OPEN: // If the valve is currently in position B, subtract the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) - nextStep; + valvesStatus[ valve ].targetPositionInCounts = currentPosition - nextStep; break; case VALVE_POSITION_C_CLOSE: // If the valve is currently in position C, add the defined number of steps for the next transition - valvesStatus[ valve ].targetPositionInCounts = getValvePositionCounts( valve ) + nextStep; + valvesStatus[ valve ].targetPositionInCounts = currentPosition + nextStep; break; default: