Index: firmware/App/Controllers/AirPump.c =================================================================== diff -u -r3fed3b31ffb5680c306669c2e3f84e7eec522478 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 3fed3b31ffb5680c306669c2e3f84e7eec522478) +++ firmware/App/Controllers/AirPump.c (.../AirPump.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-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 AirPump.c * -* @author (last) Sean -* @date (last) 17-Sep-2024 +* @author (last) Sean Nash +* @date (last) 29-Jul-2025 * -* @author (original) Sean -* @date (original) 17-Sep-2024 +* @author (original) Sean Nash +* @date (original) 19-Sep-2024 * ***************************************************************************/ Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r7fa60180faff90527b27843cbf6e4de21c566505 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 7fa60180faff90527b27843cbf6e4de21c566505) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-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 AirTrap.c * -* @author (last) Sean -* @date (last) 03-Oct-2024 +* @author (last) Dara Navaei +* @date (last) 26-Oct-2025 * -* @author (original) Sean -* @date (original) 03-Oct-2024 +* @author (original) Sean Nash +* @date (original) 24-Oct-2024 * ***************************************************************************/ Index: firmware/App/Controllers/Ejector.c =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/Ejector.c (.../Ejector.c) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Controllers/Ejector.c (.../Ejector.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -30,7 +30,7 @@ // ********** private definitions ********** -#define EJECTOR_RETRACT_OP_TIME ( ( MS_PER_SECOND * 5 ) / TASK_GENERAL_INTERVAL ) ///< Ejector retract operation interval. +#define EJECTOR_RETRACT_OP_TIME ( ( MS_PER_SECOND * 10 ) / TASK_GENERAL_INTERVAL ) ///< Ejector retract operation interval. #define EJECTOR_EXTEND_OP_TIME ( ( MS_PER_SECOND * 10 ) / TASK_GENERAL_INTERVAL ) ///< Ejector extend operation interval. #define EJECTOR_BACKOFF_OP_TIME ( 50 / TASK_GENERAL_INTERVAL ) ///< Ejector back-off operation interval. #define EJECTOR_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Ejector data publish interval. @@ -43,10 +43,10 @@ /// Enumeration of ejector states. typedef enum EjectorOperations { - EJECTOR_OPERATION_HOME = 0, ///< Ejector home operation - EJECTOR_OPERATION_RETRACT, ///< Ejector retract operation - EJECTOR_OPERATION_EXTEND, ///< Ejector extend operation - NUM_OF_EJECTOR_OPERATIONS, ///< Number of ejector operations + EJECTOR_OPERATION_HOME = 0, ///< Ejector home operation + EJECTOR_OPERATION_RETRACT, ///< Ejector retract operation + EJECTOR_OPERATION_EXTEND, ///< Ejector extend operation + NUM_OF_EJECTOR_OPERATIONS, ///< Number of ejector operations } EJECTOR_OPERATION_T; // ********** private data ********** @@ -103,37 +103,6 @@ /*********************************************************************//** * @brief - * The resetEjectorFlags function resets the ejector flags to FALSE. - * @details \b Inputs: none - * @details \b Outputs: ejectorHomeRequested, ejectorRetractRequested, - * ejectorExtendRequested, ejectorAbortRequested - * @return none - *************************************************************************/ -static void resetEjectorFlags( void ) -{ - ejectorHomeRequested = FALSE; - ejectorRetractRequested = FALSE; - ejectorExtendRequested = FALSE; - ejectorAbortRequested = FALSE; -} - -/*********************************************************************//** - * @brief - * The setEjectorSpeed function records the requested ejector speed and - * sets the ejector motor speed to that speed. - * @details \b Inputs: none - * @details \b Outputs: currentEjectorSetSpeed - * @param speed Target speed for ejector motor. - * @return none - *************************************************************************/ -static void setEjectorSpeed( F32 speed ) -{ - currentEjectorSetSpeed = speed; - setEjectorMotorSpeed( currentEjectorSetSpeed ); -} - -/*********************************************************************//** - * @brief * The homeEjector function requests an ejector home operation. * @details \b Inputs: currentEjectorState * @details \b Outputs: ejectorHomeRequested @@ -336,7 +305,7 @@ { EJECTOR_STATE_T state = EJECTOR_STATE_HOMING; - if ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_TIME ) + if ( ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_TIME ) || ( TRUE == isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_RETRACT ) ) ) { ejectorOperationTimerCounter = 0; setEjectorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); @@ -410,7 +379,8 @@ { EJECTOR_STATE_T state = EJECTOR_STATE_RETRACTING; - if ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_TIME ) + // If the optical sensor is active it means the ejector has reached to the full retract position + if ( ( ++ejectorOperationTimerCounter >= EJECTOR_RETRACT_OP_TIME ) || ( TRUE == isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_RETRACT ) ) ) { ejectorOperationTimerCounter = 0; setEjectorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); @@ -476,7 +446,8 @@ { EJECTOR_STATE_T state = EJECTOR_STATE_EXTENDING; - if ( ++ejectorOperationTimerCounter >= EJECTOR_EXTEND_OP_TIME ) + // If the optical sensor is active it means the ejector has reached to the full extended (engage) position + if ( ( ++ejectorOperationTimerCounter >= EJECTOR_EXTEND_OP_TIME ) || ( TRUE == isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_ENGAGE ) ) ) { ejectorOperationTimerCounter = 0; setEjectorSpeed( EJECTOR_OFF_MOTOR_SPEED_RPM ); @@ -510,6 +481,37 @@ /*********************************************************************//** * @brief + * The resetEjectorFlags function resets the ejector flags to FALSE. + * @details \b Inputs: none + * @details \b Outputs: ejectorHomeRequested, ejectorRetractRequested, + * ejectorExtendRequested, ejectorAbortRequested + * @return none + *************************************************************************/ +static void resetEjectorFlags( void ) +{ + ejectorHomeRequested = FALSE; + ejectorRetractRequested = FALSE; + ejectorExtendRequested = FALSE; + ejectorAbortRequested = FALSE; +} + +/*********************************************************************//** + * @brief + * The setEjectorSpeed function records the requested ejector speed and + * sets the ejector motor speed to that speed. + * @details \b Inputs: none + * @details \b Outputs: currentEjectorSetSpeed + * @param speed Target speed for ejector motor. + * @return none + *************************************************************************/ +static void setEjectorSpeed( F32 speed ) +{ + currentEjectorSetSpeed = speed; + setEjectorMotorSpeed( currentEjectorSetSpeed ); +} + +/*********************************************************************//** + * @brief * The publishEjectorData function constructs and sends the air pump data * broadcast message. * @details \b Message \b Sent: MSG_ID_TD_EJECTOR_DATA @@ -524,8 +526,10 @@ { EJECTOR_PAYLOAD_T data; - data.h5State = getEjectorState(); - data.h5SetSpeed = currentEjectorSetSpeed; + data.h5State = getEjectorState(); + data.h5SetSpeed = currentEjectorSetSpeed; + data.retractOpticalSensor = (U32)isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_RETRACT ); + data.engageOpticalSensor = (U32)isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_ENGAGE ); broadcastData( MSG_ID_TD_EJECTOR_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( EJECTOR_PAYLOAD_T ) ); ejectorDataPublicationTimerCounter = 0; Index: firmware/App/Controllers/Ejector.h =================================================================== diff -u -rcf22584fb68bb29311d81d1e5ad79f8cf064b8fb -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/Ejector.h (.../Ejector.h) (revision cf22584fb68bb29311d81d1e5ad79f8cf064b8fb) +++ firmware/App/Controllers/Ejector.h (.../Ejector.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -7,11 +7,11 @@ * * @file Ejector.h * -* @author (last) Sean -* @date (last) 17-Sep-2024 +* @author (last) Dara Navaei +* @date (last) 28-Jul-2025 * -* @author (original) Sean -* @date (original) 17-Sep-2024 +* @author (original) Sean Nash +* @date (original) 15-May-2025 * ***************************************************************************/ Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -43,7 +43,9 @@ #define VALVE_FORCE_HOME TRUE ///< Force valve to home even if already homed. #define ZERO_ENC_DEBOUNCE_THRESHOLD_CNT 5 ///< Valves zero encoder debounce threshold count. #define ZERO_ENC_DEBOUNCE_TIMEOUT_MS ( 0.25 * MS_PER_SECOND ) ///< Valves zero encoder debounce timeout in milliseconds. -#define POS_D_PARTIAL_CLOSE_FROM_ZERO_CNT 32 ///< Position D partial close from zero position in counts. +#define VALVE_OFFEST_FROM_EDG_CNT 296 ///< Valves offset from the edge. +#define POS_C_FROM_ZERO_CNT VALVE_OFFEST_FROM_EDG_CNT ///< Position C from zero position in counts. +#define POS_D_PARTIAL_CLOSE_FROM_ZERO_CNT ( POS_C_FROM_ZERO_CNT + 32 ) ///< Position D partial close from zero position in counts. /// Valve controller states typedef enum Valve_Control_States @@ -54,21 +56,12 @@ VALVE_STATE_ENABLE_VALVE, ///< Valve state enable valve. VALVE_STATE_HOMING_NOT_STARTED, ///< Valve state homing not started. VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE, ///< Valve state homing find energized edge. + VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE, ///< Valve state homing find de-energized edge. VALVE_STATE_IDLE, ///< Valve state idle. VALVE_STATE_IN_TRANSITION, ///< Valve state in transition. NUM_OF_VALVE_STATES, ///< Number of valve exec states. } VALVE_STATE_T; -/// Valve homing status -typedef enum Valve_Homing_Status -{ - VALVE_HOMING_INIT = 0, ///< Valve homing init. - VALVE_HOMING_FORWARD, ///< Valve homing forward. - VALVE_HOMING_REVERSE, ///< Valve homing reverse. - VALVE_HOMING_COMPLETE, ///< Valve homing complete. - NUM_OF_VALVE_HOMING_STATE, ///< Number of valve homing. -} VALVE_HOMING_STATUS_T; - /// Valve status structure typedef struct { @@ -86,10 +79,9 @@ // Homing variables BOOL hasHomingBeenRequested; ///< Valve homing request flag. BOOL hasValveBeenHomed; ///< Valve homing completed flag. - BOOL hasHomingFailed; ///< Valve homing failed flag - S16 proposedEnergizedPos; ///< Valve homing proposed energized position. BOOL hasValveBeenReset; ///< Valve homing has valve been reset. - VALVE_HOMING_STATUS_T valveHomingStatus; ///< Valve homing status. + S16 currentMaxEncPositionCnt; ///< Valve homing current maximum encoder position counts. + S16 previousMaxEncPositionCnt; ///< Valve homing previous maximum encoder position counts. } VALVE_STATUS_T; /// Payload record structure for pinch valve set position request @@ -123,9 +115,12 @@ static VALVE_STATE_T handleValvesEnableValve( VALVE_T valve ); static VALVE_STATE_T handleValvesNotHomedState( VALVE_T valve ); static VALVE_STATE_T handleValvesFindEnergizedEdgeState( VALVE_T valve ); +static VALVE_STATE_T handleValvesFindDeenergizedEdgeState( VALVE_T valve ); static VALVE_STATE_T handleValvesIdleState( VALVE_T valve ); static VALVE_STATE_T handleValvesTransitionState( VALVE_T valve ); static void checkValveInRange( VALVE_T valve, SW_FAULT_ID_T SWFault ); +static BOOL hasEdgeBeenReached( VALVE_T valve ); +static S16 convertCountToDivision8( S16 count ); static void publishValvesData( void ); /*********************************************************************//** @@ -272,9 +267,12 @@ for ( valve = FIRST_VALVE; valve < NUM_OF_VALVES; valve++ ) { - // update valve encoder positions - currentValveStates[ valve ].priorEncPosition = currentValveStates[ valve ].currentEncPosition; - currentValveStates[ valve ].currentEncPosition = getValveEncoderPosition( valve ); + // Update valve encoder positions + currentValveStates[ valve ].priorEncPosition = currentValveStates[ valve ].currentEncPosition; + currentValveStates[ valve ].currentEncPosition = getValveEncoderPosition( valve ); + // Update valve max encoder positions + currentValveStates[ valve ].previousMaxEncPositionCnt = currentValveStates[ valve ].currentMaxEncPositionCnt; + currentValveStates[ valve ].currentMaxEncPositionCnt = getValveMaximumEncoderPosition( valve ); // execute valve state machine switch ( currentValveStates[ valve ].controlState ) @@ -303,6 +301,10 @@ currentValveStates[ valve ].controlState = handleValvesFindEnergizedEdgeState( valve ); break; + case VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE: + currentValveStates[ valve ].controlState = handleValvesFindDeenergizedEdgeState( valve ); + break; + case VALVE_STATE_IDLE: currentValveStates[ valve ].controlState = handleValvesIdleState( valve ); break; @@ -322,6 +324,31 @@ /*********************************************************************//** * @brief + * The execValvesSelfTest function executes the valves self-test. Calibration + * factors are loaded from non-volatile memory and CRC checked. + * @details \b Inputs: Calibration record stored in non-volatile memory. + * @details \b Outputs: valvesCalibrationRecord + * @return self-test result (pass/fail) + *************************************************************************/ +SELF_TEST_STATUS_T execValvesSelfTest( void ) +{ + BOOL calStatus = TRUE; /* TODO getNVRecord2Driver( GET_CAL_VALVES, (U08*)&valvesCalibrationRecord, sizeof( HD_VALVES_CAL_RECORD_T ), + NUM_OF_CAL_DATA_HD_VALVES, ALARM_ID_NO_ALARM );*/ + + if ( TRUE == calStatus ) + { + valvesSelfTestResult = SELF_TEST_STATUS_PASSED; + } + else + { + valvesSelfTestResult = SELF_TEST_STATUS_FAILED; + } + + return valvesSelfTestResult; +} + +/*********************************************************************//** + * @brief * The handleValvesWait4PostState function handles the Wait for POST state * of the state machine for a given valve. * @details \b Inputs: current operating mode @@ -411,16 +438,12 @@ if ( valveEncPosistion >= ZERO_ENC_DEBOUNCE_THRESHOLD_CNT ) { - // Keep reseting the debouce timer until the encoder count is less than the encoder count is less than the number + // Keep reseting the debounce timer until the encoder count is less than the encoder count is less than the number currentValveStates[ valve ].valveOpsStartTime = getMSTimerCount(); } else if ( TRUE == didTimeout( currentValveStates[ valve ].valveOpsStartTime, ZERO_ENC_DEBOUNCE_TIMEOUT_MS ) ) { - // Position C is hard coded as count 8. - // Position D is hard coded as an offset form 0. - currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ] = ROTARY_VALVE_MICROSTEP_FRACTION; - currentValveStates[ valve ].positionsABC[ VALVE_POSITION_D_PARTIAL_CLOSE ] = POS_D_PARTIAL_CLOSE_FROM_ZERO_CNT; - nextState = VALVE_STATE_HOMING_NOT_STARTED; + nextState = VALVE_STATE_HOMING_NOT_STARTED; } return nextState; @@ -443,52 +466,27 @@ if ( TRUE == currentValveStates[ valve ].hasHomingBeenRequested ) { - currentValveStates[ valve ].proposedEnergizedPos = ROTARY_VALVE_INIT_FULL_SWING_COUNTS; + // Getting ready for homing enable the homing bit upon transitioning to homing not started + setValveHomingEnableDisable( valve, TRUE ); - //switch ( currentValveStates[ valve ].valveHomingStatus ) - //{ - // case VALVE_HOMING_INIT: - // currentValveStates[ valve ].proposedEnergizedPos = 1880; //ROTARY_VALVE_INIT_FULL_SWING_COUNTS; - // break; - // - // case VALVE_HOMING_FORWARD: - // currentValveStates[ valve ].proposedEnergizedPos += ROTARY_VALVE_MICROSTEP_FRACTION; - // break; - // - // case VALVE_HOMING_REVERSE: - // currentValveStates[ valve ].proposedEnergizedPos -= ROTARY_VALVE_MICROSTEP_FRACTION; - // break; - // - // default: - // // Do nothing as complete has nothing to do - // break; - //} + // TODO figure out the new valve homing failure alarm + // SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_VALVE_HOMING_FAILED, (U32)valve, (U32)currentValveStates[ valve ].proposedEnergizedPos ) - if ( ( currentValveStates[ valve ].proposedEnergizedPos <= ROTARY_VALVE_ENERGIZED_EDGE_MIN_COUNTS ) || - ( currentValveStates[ valve ].proposedEnergizedPos >= ROTARY_VALVE_ENERGIZED_EDGE_MAX_COUNTS ) ) - { - currentValveStates[ valve ].hasHomingFailed = TRUE; - currentValveStates[ valve ].hasHomingBeenRequested = FALSE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_VALVE_HOMING_FAILED, (U32)valve, (U32)currentValveStates[ valve ].proposedEnergizedPos ) - } - else - { - // Command valve to move to energized edge (end of travel) - currentValveStates[ valve ].valveOpsStartTime = 0; - currentValveStates[ valve ].hasValveBeenHomed = FALSE; - currentValveStates[ valve ].currentPosition = VALVE_POSITION_NOT_IN_POSITION; - nextState = VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE; - setValveCmdChangePosition( valve, (U16)currentValveStates[ valve ].proposedEnergizedPos, MOTOR_DIR_FORWARD ); - } + // Command valve to move to energized edge (end of travel) + currentValveStates[ valve ].valveOpsStartTime = 0; + currentValveStates[ valve ].hasValveBeenHomed = FALSE; + currentValveStates[ valve ].currentPosition = VALVE_POSITION_NOT_IN_POSITION; + nextState = VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE; + setValveCmdChangePosition( valve, (U16)ROTARY_VALVE_INIT_ENERGIZED_COUNTS, MOTOR_DIR_FORWARD ); } return nextState; } /*********************************************************************//** * @brief - * The handleValvesFindEnergizedEdgeState function handles the Find Energized - * Edge state of the state machine for a given valve. + * The handleValvesFindEnergizedEdgeState function handles the find energized + * edge state of the state machine for a given valve. * @details \b Inputs: currentValveStates[] * @details \b Outputs: currentValveStates[] * @param valve ID of valve for which to handle the Find Energized Edge state @@ -497,71 +495,56 @@ static VALVE_STATE_T handleValvesFindEnergizedEdgeState( VALVE_T valve ) { VALVE_STATE_T nextState = VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE; - S16 curPos = currentValveStates[ valve ].currentEncPosition; checkValveInRange( valve, SW_FAULT_ID_TD_VALVES_INVALID_FIND_ENERGIZED_EDGE ); - // have we found forward edge of travel? - if ( abs( curPos - currentValveStates[ valve ].priorEncPosition ) < VALVE_HOME_MIN_POS_CHG ) + if ( TRUE == hasEdgeBeenReached( valve ) ) { - if ( 0 == currentValveStates[ valve ].valveOpsStartTime ) - { - currentValveStates[ valve ].valveOpsStartTime = getMSTimerCount(); - } - else if ( TRUE == didTimeout( currentValveStates[ valve ].valveOpsStartTime, HOMING_EDGE_DETECTION_TIMEOUT_MS ) ) - { - //if ( VALVE_HOMING_INIT == currentValveStates[ valve ].valveHomingStatus ) - //{ - // S16 tgtPos = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ]; - // S16 mag = curPos - tgtPos; // calculate magnitude of position change - // - // // Set commanded position and transition start time stamp - // // Transition back to position C to try the next energized position. It has to start from position C - // currentValveStates[ valve ].commandedPosition = VALVE_POSITION_C_CLOSE; - // currentValveStates[ valve ].valveOpsStartTime = getMSTimerCount(); - // currentValveStates[ valve ].valveHomingStatus = VALVE_HOMING_FORWARD; - // nextState = VALVE_STATE_IN_TRANSITION; - // // Command FPGA to move valve to commanded position - // setValveCmdChangePosition( valve, (U16)(mag), MOTOR_DIR_REVERSE ); - //} - //else - { - S16 posC = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ]; - S16 posA = posC + ( ( curPos - posC ) / 2 ); + nextState = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; + } - // If position A was calculated to not be a division of 8 it is rounded down to be a division of 8 - posA = ( posA % ROTARY_VALVE_MICROSTEP_FRACTION ) < 4 ? ( posA >> 3 ) << 3 : posA; + return nextState; +} - currentValveStates[ valve ].positionsABC[ VALVE_POSITION_B_OPEN ] = curPos; - currentValveStates[ valve ].positionsABC[ VALVE_POSITION_A_INSERT_EJECT ] = posA; - currentValveStates[ valve ].hasValveBeenHomed = TRUE; - currentValveStates[ valve ].currentPosition = VALVE_POSITION_B_OPEN; - currentValveStates[ valve ].pendingCommandedPosition = VALVE_POSITION_A_INSERT_EJECT; - currentValveStates[ valve ].valveHomingStatus = VALVE_HOMING_COMPLETE; - currentValveStates[ valve ].hasTransitionBeenRequested = TRUE; - currentValveStates[ valve ].hasHomingBeenRequested = FALSE; - nextState = VALVE_STATE_IDLE; - } - } - } - else if ( curPos <= 0 ) - { - switch ( currentValveStates[ valve ].valveHomingStatus ) - { - case VALVE_HOMING_INIT: - case VALVE_HOMING_FORWARD: - currentValveStates[ valve ].valveHomingStatus = VALVE_HOMING_REVERSE; - break; +/*********************************************************************//** + * @brief + * The handleValvesFindDeenergizedEdgeState function handles the find Deenergized + * edge state of the state machine for a given valve. + * @details \b Inputs: currentValveStates[] + * @details \b Outputs: currentValveStates[] + * @param valve ID of valve for which to handle the find deenergized edge state + * @return next state of the state machine for the given valve + *************************************************************************/ +static VALVE_STATE_T handleValvesFindDeenergizedEdgeState( VALVE_T valve ) +{ + VALVE_STATE_T nextState = VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE; + S16 posB = 0; + S16 posC = 0; + S16 posA = 0; - default: - // If init or forward modes, then reverse again. - break; - } + checkValveInRange( valve, SW_FAULT_ID_TD_VALVES_INVALID_FIND_DEENERGIZED_EDGE ); - currentValveStates[ valve ].hasValveBeenReset = FALSE; - nextState = VALVE_STATE_RESET_VALVE; - } + // Done with homing disable the homing bit + setValveHomingEnableDisable( valve, FALSE ); + // TODO in the future this needs to be searched + currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ] = VALVE_OFFEST_FROM_EDG_CNT; + // TODO in the future this needs to be searched + currentValveStates[ valve ].positionsABC[ VALVE_POSITION_D_PARTIAL_CLOSE ] = POS_D_PARTIAL_CLOSE_FROM_ZERO_CNT; + + posB = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_B_OPEN ]; + posC = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ]; + posA = posC + ( ( posB - posC ) / 2 ); + posA = convertCountToDivision8( posA ); + + currentValveStates[ valve ].positionsABC[ VALVE_POSITION_A_INSERT_EJECT ] = posA; + currentValveStates[ valve ].hasValveBeenHomed = TRUE; + currentValveStates[ valve ].currentPosition = VALVE_POSITION_B_OPEN; + currentValveStates[ valve ].pendingCommandedPosition = VALVE_POSITION_A_INSERT_EJECT; + currentValveStates[ valve ].hasTransitionBeenRequested = TRUE; + currentValveStates[ valve ].hasHomingBeenRequested = FALSE; + nextState = VALVE_STATE_IDLE; + return nextState; } @@ -583,26 +566,10 @@ // handle a home request if ( TRUE == currentValveStates[ valve ].hasHomingBeenRequested ) { - if ( VALVE_HOMING_COMPLETE == currentValveStates[ valve ].valveHomingStatus ) - { - S16 tgtPos = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ]; - S16 mag = currentValveStates[ valve ].currentEncPosition - tgtPos; // calculate magnitude of position change - - // Set commanded position and transition start time stamp - // Transition back to position C to try the next energized position. It has to start from position C - currentValveStates[ valve ].commandedPosition = VALVE_POSITION_C_CLOSE; - currentValveStates[ valve ].valveOpsStartTime = getMSTimerCount(); - currentValveStates[ valve ].valveHomingStatus = VALVE_HOMING_INIT; - currentValveStates[ valve ].hasValveBeenReset = FALSE; - nextState = VALVE_STATE_IN_TRANSITION; - // Command FPGA to move valve to commanded position - setValveCmdChangePosition( valve, (U16)(mag), MOTOR_DIR_REVERSE ); - } - else if ( VALVE_HOMING_INIT == currentValveStates[ valve ].valveHomingStatus ) - { - currentValveStates[ valve ].hasValveBeenReset = FALSE; - nextState = VALVE_STATE_HOMING_NOT_STARTED; - } + // Homing has been requested, enable the homing bit. + setValveHomingEnableDisable( valve, TRUE ); + // Transition to enable homing to set the encode to 0. + nextState = VALVE_STATE_ENABLE_VALVE; } // handle a position change request else if ( TRUE == currentValveStates[ valve ].hasTransitionBeenRequested ) @@ -650,7 +617,7 @@ if ( abs( delta ) < VALVE_TRANSITION_MIN_TGT_DELTA ) { currentValveStates[ valve ].currentPosition = currentValveStates[ valve ].commandedPosition; - nextState = ( VALVE_HOMING_COMPLETE != currentValveStates[ valve ].valveHomingStatus ? VALVE_STATE_HOMING_NOT_STARTED : VALVE_STATE_IDLE ); + nextState = VALVE_STATE_IDLE; } // is transition taking too long? else if ( ( TRUE == didTimeout( currentValveStates[ valve ].valveOpsStartTime, VALVE_TRANSITION_TIMEOUT_MS ) ) && @@ -673,46 +640,87 @@ /*********************************************************************//** * @brief - * The execValvesSelfTest function executes the valves self-test. Calibration - * factors are loaded from non-volatile memory and CRC checked. - * @details \b Inputs: Calibration record stored in non-volatile memory. - * @details \b Outputs: valvesCalibrationRecord - * @return self-test result (pass/fail) + * The checkValveInRange function checks whether the selected valve is in range + * and if not it will trigger the provided software fault. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given valve is invalid. + * @details \b Inputs: none + * @details \b Outputs: none + * @param valve the valve check whether it is in range + * @param SWFault the provided software fault to trigger + * @return none *************************************************************************/ -SELF_TEST_STATUS_T execValvesSelfTest( void ) +static void checkValveInRange( VALVE_T valve, SW_FAULT_ID_T SWFault ) { - BOOL calStatus = TRUE; /* TODO getNVRecord2Driver( GET_CAL_VALVES, (U08*)&valvesCalibrationRecord, sizeof( HD_VALVES_CAL_RECORD_T ), - NUM_OF_CAL_DATA_HD_VALVES, ALARM_ID_NO_ALARM );*/ + if ( valve >= NUM_OF_VALVES ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, (U32)SWFault, (U32)valve ) + } +} - if ( TRUE == calStatus ) +/*********************************************************************//** + * @brief + * The hasEdgeBeenReached function checks whether the valve has reached to + * its edge or not. + * @details \b Inputs: currentValveStates[] + * @details \b Outputs: currentValveStates[] + * @param valve ID of valve for which to check its edge + * @return TRUE if the edge has been reached otherwise, FALSE + *************************************************************************/ +static BOOL hasEdgeBeenReached( VALVE_T valve ) +{ + BOOL status = FALSE; + S16 previousMaxEnc = currentValveStates[ valve ].previousMaxEncPositionCnt; + S16 currentMaxEnc = currentValveStates[ valve ].currentMaxEncPositionCnt; + + checkValveInRange( valve, SW_FAULT_ID_VALVES_INVALID_VALVE_FINDING_EDGE ); + + if ( abs( currentMaxEnc - previousMaxEnc ) < VALVE_HOME_MIN_POS_CHG ) { - valvesSelfTestResult = SELF_TEST_STATUS_PASSED; + if ( 0 == currentValveStates[ valve ].valveOpsStartTime ) + { + currentValveStates[ valve ].valveOpsStartTime = getMSTimerCount(); + } + else if ( TRUE == didTimeout( currentValveStates[ valve ].valveOpsStartTime, HOMING_EDGE_DETECTION_TIMEOUT_MS ) ) + { + status = TRUE; + currentMaxEnc = convertCountToDivision8( currentMaxEnc ); + currentMaxEnc -= VALVE_OFFEST_FROM_EDG_CNT; + + currentValveStates[ valve ].valveOpsStartTime = 0; + + if ( VALVE_STATE_HOMING_FIND_ENERGIZED_EDGE == currentValveStates[ valve ].controlState ) + { + currentValveStates[ valve ].positionsABC[ VALVE_POSITION_B_OPEN ] = currentMaxEnc; + } + // TODO uncomment the deenergized edge + //else if ( VALVE_STATE_HOMING_FIND_DEENERGIZED_EDGE == currentValveStates[ valve ].controlStat ) + //{ + // currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ] = currentMaxEnc + //} + } } else { - valvesSelfTestResult = SELF_TEST_STATUS_FAILED; + currentValveStates[ valve ].valveOpsStartTime = 0; } - return valvesSelfTestResult; + return status; } /*********************************************************************//** * @brief - * The checkValveInRange function checks whether the selected valve is in range - * and if not it will trigger the provided software fault. - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given valve is invalid. + * The convertCountToDivision8 function converts the provided data to be in + * division of 8. * @details \b Inputs: none * @details \b Outputs: none - * @param valve the valve check whether it is in range - * @param SWFault the provided software fault to trigger - * @return none + * @param count the value to be converted to the division of 8 + * @return the converted value *************************************************************************/ -static void checkValveInRange( VALVE_T valve, SW_FAULT_ID_T SWFault ) +static S16 convertCountToDivision8( S16 count ) { - if ( valve >= NUM_OF_VALVES ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, (U32)SWFault, (U32)valve ) - } + S16 convCount = ( count >> 3 ) << 3; + + return convCount; } /*********************************************************************//** @@ -743,6 +751,7 @@ data.posB = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_B_OPEN ]; data.posC = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_C_CLOSE ]; data.posD = currentValveStates[ valve ].positionsABC[ VALVE_POSITION_D_PARTIAL_CLOSE ]; + data.maxHomingPos = currentValveStates[ valve ].currentMaxEncPositionCnt; broadcastData( MSG_ID_TD_VALVES_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( TD_VALVE_DATA_T ) ); } Index: firmware/App/Controllers/Valves.h =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Controllers/Valves.h (.../Valves.h) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Controllers/Valves.h (.../Valves.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -57,6 +57,7 @@ S16 posB; ///< Position B (count) S16 posC; ///< Position C (count) S16 posD; ///< Position D (count) + S16 maxHomingPos; ///< Maximum homing position } TD_VALVE_DATA_T; #pragma pack(pop) Index: firmware/App/Drivers/EjectorMotor.c =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Drivers/EjectorMotor.c (.../EjectorMotor.c) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Drivers/EjectorMotor.c (.../EjectorMotor.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -49,6 +49,9 @@ #define EJECTOR_MOTOR_CONTROL_32TH_STEP 0x03 ///< Ejector motor control register bits for 1/32 micro-stepping mode. #define EJECTOR_MOTOR_CONTROL_FULL_STEP 0x00 ///< Ejector motor control register bits for full stepping mode. +#define EJECTOR_OPT_SENSOR_ACTIVE 0 ///< Ejector optical sensor active. +#define EJECTOR_OPT_SENSOR_INACTIVE 1 ///< Ejector optical sensor inactive. + /// Control bits to run ejector motor in reverse direction static const U08 EJECTOR_MOTOR_CONTROL_RUN_REVERSE = EJECTOR_MOTOR_CONTROL_SLEEP_OFF | EJECTOR_MOTOR_CONTROL_NOT_RESET | @@ -63,24 +66,22 @@ EJECTOR_MOTOR_CONTROL_32TH_STEP; /// Control bits to disable ejector motor -static const U08 EJECTOR_MOTOR_CONTROL_DISABLED = EJECTOR_MOTOR_CONTROL_SLEEP_OFF | - EJECTOR_MOTOR_CONTROL_NOT_RESET | - EJECTOR_MOTOR_CONTROL_FORWARD_DIR | - EJECTOR_MOTOR_CONTROL_32TH_STEP; +static const U08 EJECTOR_MOTOR_CONTROL_DISABLED = 0; /// Payload record structure for ejector motor set request typedef struct { - F32 setSpeed; ///< Set speed for ejector motor (in RPM). Negative RPM indicates reverse direction. + F32 setSpeed; ///< Set speed for ejector motor (in RPM). Negative RPM indicates reverse direction. } EJECTOR_MOTOR_SET_CMD_PAYLOAD_T; // ********** private data ********** -static F32 currentEjectorMotorSetSpeed; ///< Current ejector motor set speed (in RPM). -static U32 ejectorMotorSetToggleTime; ///< Time (in uSec) between microstep toggles. -static U32 ejectorMotorRampUpToggleTime; ///< Current ramp time (in uSec) between microstep toggles. -static U32 ejectorMotorRampTimerCtr; ///< Used to track ramp up time. -static BOOL ejectorMotorRampUpInProgress; ///< Flag indicating whether a ramp up is in progress. +static F32 currentEjectorMotorSetSpeed; ///< Current ejector motor set speed (in RPM). +static U32 ejectorMotorSetToggleTime; ///< Time (in uSec) between microstep toggles. +static U32 ejectorMotorRampUpToggleTime; ///< Current ramp time (in uSec) between microstep toggles. +static U32 ejectorMotorRampTimerCtr; ///< Used to track ramp up time. +static BOOL ejectorMotorRampUpInProgress; ///< Flag indicating whether a ramp up is in progress. +static OVERRIDE_U32_T ejectorOpticalSensors[ NUM_OF_EJECTOR_OPT_SENSORS ]; ///< Ejector retract optical sensor. // ********** private function prototypes ********** @@ -95,12 +96,22 @@ *************************************************************************/ void initEjectorMotor(void) { + U32 optSensor; + currentEjectorMotorSetSpeed = 0.0F; ejectorMotorSetToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; ejectorMotorRampUpToggleTime = EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP; ejectorMotorRampTimerCtr = 0; ejectorMotorRampUpInProgress = FALSE; + for ( optSensor = EJECTOR_OPT_SENSOR_RETRACT; optSensor < NUM_OF_EJECTOR_OPT_SENSORS; optSensor++ ) + { + ejectorOpticalSensors[ optSensor ].data = EJECTOR_OPT_SENSOR_INACTIVE; + ejectorOpticalSensors[ optSensor ].ovData = 0; + ejectorOpticalSensors[ optSensor ].ovInitData = 0; + ejectorOpticalSensors[ optSensor ].override = OVERRIDE_RESET; + } + setH5StepToggleTime( ejectorMotorSetToggleTime ); setH5ControlFlags( EJECTOR_MOTOR_CONTROL_DISABLED ); } @@ -116,7 +127,7 @@ *************************************************************************/ void disableEjectorMotor( void ) { - if ( ejectorMotorSetToggleTime != EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP ) + if ( EJECTOR_MOTOR_MICROSTEP_TOGGLE_TIME_FOR_STOP == ejectorMotorSetToggleTime ) { setH5ControlFlags( EJECTOR_MOTOR_CONTROL_DISABLED ); } @@ -195,6 +206,11 @@ *************************************************************************/ void execEjectorMotorRamping( void ) { + // Update the optical sensor values + // TODO is debouncing needed?? + ejectorOpticalSensors[ EJECTOR_OPT_SENSOR_RETRACT ].data = getFPGAEjectorRetractOpticalSensor(); + ejectorOpticalSensors[ EJECTOR_OPT_SENSOR_ENGAGE ].data = getFPGAEjectorEngageOpticalSensor(); + if ( TRUE == ejectorMotorRampUpInProgress ) { ejectorMotorRampTimerCtr++; @@ -218,6 +234,39 @@ /*********************************************************************//** * @brief + * The isEjectorOpticalSensorActive function checks whether either of the + * ejector optical sensors are active or inactive. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if the ejector optical sensor + * is not in range. + * @details Inputs: ejectorOpticalSensors + * @details Outputs: none + * @param rsensorID the optical sensor to check + * @return TRUE if the sensor is active otherwise, FALSE + *************************************************************************/ +BOOL isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_T sensorID ) +{ + BOOL status = FALSE; + + switch ( sensorID ) + { + case EJECTOR_OPT_SENSOR_RETRACT: + status = ( EJECTOR_OPT_SENSOR_ACTIVE == getU32OverrideValue( &ejectorOpticalSensors[ EJECTOR_OPT_SENSOR_RETRACT ] ) ? TRUE : FALSE ); + break; + + case EJECTOR_OPT_SENSOR_ENGAGE: + status = ( EJECTOR_OPT_SENSOR_ACTIVE == getU32OverrideValue( &ejectorOpticalSensors[ EJECTOR_OPT_SENSOR_ENGAGE ] ) ? TRUE : FALSE ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TD_EJECTOR_OPTICAL_SENSOR_INVALID_REQ, (U32)sensorID ) + break; + } + + return status; +} + +/*********************************************************************//** + * @brief * The calcEjectorStepToggleTimeFromSetSpeed function calculates the stepper * toggle period for a given set speed (in RPM). * @details Inputs: none @@ -283,5 +332,21 @@ return result; } +/*********************************************************************//** + * @brief + * The testEjectorOpticalSensorOverride function overrides the optical sensors. + * @details \b Inputs: none + * @details \b Outputs: ejectorOpticalSensors + * @param message Override message from Dialin which includes the sensor to + * override its value. + * @return TRUE if override request is successful, FALSE if not + *************************************************************************/ +BOOL testEjectorOpticalSensorOverride( MESSAGE_T *message ) +{ + BOOL result = u32ArrayOverride( message, &ejectorOpticalSensors[ EJECTOR_OPT_SENSOR_RETRACT ], NUM_OF_EJECTOR_OPT_SENSORS - 1, EJECTOR_OPT_SENSOR_ACTIVE, EJECTOR_OPT_SENSOR_INACTIVE ); + + return result; +} + /**@}*/ Index: firmware/App/Drivers/EjectorMotor.h =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Drivers/EjectorMotor.h (.../EjectorMotor.h) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Drivers/EjectorMotor.h (.../EjectorMotor.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -33,15 +33,25 @@ // ********** public definitions ********** +/// Enumeration of the ejector optical sensor +typedef enum +{ + EJECTOR_OPT_SENSOR_RETRACT = 0, ///< Ejector optical sensor retract. + EJECTOR_OPT_SENSOR_ENGAGE, ///< Ejector optical sensor engage. + NUM_OF_EJECTOR_OPT_SENSORS ///< Num of ejector optical sensors. +} EJECTOR_OPT_SENSOR_T; + // ********** public function prototypes ********** void initEjectorMotor( void ); void disableEjectorMotor( void ); BOOL setEjectorMotorSpeed( F32 rpm ); F32 getEjectorMotorSetSpeed( void ); void execEjectorMotorRamping( void ); +BOOL isEjectorOpticalSensorActive( EJECTOR_OPT_SENSOR_T sensorID ); BOOL testSetEjectorMotorSpeed( MESSAGE_T *message ); +BOOL testEjectorOpticalSensorOverride( MESSAGE_T *message ); /**@}*/ Index: firmware/App/Drivers/PressureSensor.c =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Drivers/PressureSensor.c (.../PressureSensor.c) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Drivers/PressureSensor.c (.../PressureSensor.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -32,8 +32,15 @@ #define PRES_SENSORS_ZERO_OFFSET ( 1638.0F ) ///< Zero offset for pressure sensor readings. #define PRES_SENSORS_DIVISOR ( 14745.0F - PRES_SENSORS_ZERO_OFFSET ) ///< Divisor for pressure sensor conversion from counts to bars. +#if 0 +// This is for the 15psi pressure sensors in the future +#define PRESSURE_MIN_PSI ( -15.0F ) ///< Minimum of scale for pressure sensor reading (in PSI). +#define PRESSURE_MAX_PSI ( 15.0F ) ///< Maximum of scale for pressure sensor reading (in PSI). +#else +// Current pressure sensors are 30psi range #define PRESSURE_MIN_PSI ( -30.0F ) ///< Minimum of scale for pressure sensor reading (in PSI). #define PRESSURE_MAX_PSI ( 30.0F ) ///< Maximum of scale for pressure sensor reading (in PSI). +#endif #define PSI_TO_MMHG ( 51.7149F ) ///< Conversion factor for converting PSI to mmHg. #define PRES_SENSORS_COUNT_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Pressure sensors read and error count timeout in milliseconds. Index: firmware/App/Drivers/RotaryValve.c =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Drivers/RotaryValve.c (.../RotaryValve.c) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Drivers/RotaryValve.c (.../RotaryValve.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -133,6 +133,7 @@ { if ( valve < NUM_OF_VALVES ) { + // TODO this line is not needed because the positions are calculated in the homing U16 mag8 = ( ( mag % ROTARY_VALVE_MICROSTEP_FRACTION ) < 4 ? ( mag >> 3 ) << 3 : ( ( mag >> 3 ) << 3 ) + ROTARY_VALVE_MICROSTEP_FRACTION ); // round to multiple of 8 to maximize holding torque S16 chgSteps = (S16)mag8 * ( MOTOR_DIR_REVERSE == dir ? -1 : 1 ); // convert to signed change in position - negative value indicates reverse direction @@ -185,36 +186,6 @@ /*********************************************************************//** * @brief - * The getValveStatus function gets the current status for a given valve. - * Status bits: - * 0-motor driver fault - * 1-direction fault - * 2-incorrect encoder sensor fault - * 3..7-reserved - * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid valve given. - * @details \b Inputs: valveStatus[] - * @details \b Outputs: none - * @param valve ID of valve to get status for - * @return Status for the given valve - *************************************************************************/ -static U08 getValveStatus( VALVE_T valve ) -{ - U08 result = 0; - - if ( valve < NUM_OF_VALVES ) - { - result = getU08OverrideValue( &valveStatus[ valve ] ); - } - else - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE4, (U32)valve ) - } - - return result; -} - -/*********************************************************************//** - * @brief * The resetValve function resets the valve. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid valve given. * @details \b Inputs: none @@ -331,7 +302,118 @@ } } +/*********************************************************************//** + * @brief + * The setValveHomingEnableDisable function enables or disables the homing + * bit in the valve's control set. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid valve given. + * @details \b Inputs: none + * @details \b Outputs: none + * @param valve ID of valve to get status for + * @param enableHoming TRUE if enable homing needed otherwise, FALSE + * @return none + *************************************************************************/ +void setValveHomingEnableDisable( VALVE_T valve, BOOL enableHoming ) +{ + U08 valveControlSet; + switch ( valve ) + { + case H1_VALV: + valveControlSet = getH1Control(); + if ( TRUE == enableHoming ) + { + valveControlSet |= FPGA_PINCH_VALVES_ENABLE_HOMING; + } + else + { + valveControlSet &= ~FPGA_PINCH_VALVES_ENABLE_HOMING; + } + setH1Control( valveControlSet ); + break; + + case H19_VALV: + valveControlSet = getH19Control(); + if ( TRUE == enableHoming ) + { + valveControlSet |= FPGA_PINCH_VALVES_ENABLE_HOMING; + } + else + { + valveControlSet &= ~FPGA_PINCH_VALVES_ENABLE_HOMING; + } + setH19Control( valveControlSet ); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_HOMING_SET, (U32)valve ) + break; + } +} + +/*********************************************************************//** + * @brief + * The getValveMaximumEncoderPosition function gets the maximum encoder + * position of the valve. + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid valve given. + * @details \b Inputs: none + * @details \b Outputs: none + * @param valve ID of valve to get status for + * @return gets the valves maximum encoder position + *************************************************************************/ +S16 getValveMaximumEncoderPosition( VALVE_T valve ) +{ + S16 maxEncoderValue; + + switch ( valve ) + { + case H1_VALV: + maxEncoderValue = getH1MaxEncPosition(); + break; + + case H19_VALV: + maxEncoderValue = getH19MaxEncPosition(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_MAX_ENC_POS_REQ, (U32)valve ) + break; + } + + return maxEncoderValue; +} + +/*********************************************************************//** + * @brief + * The getValveStatus function gets the current status for a given valve. + * Status bits: + * 0-motor driver fault + * 1-direction fault + * 2-incorrect encoder sensor fault + * 3..7-reserved + * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid valve given. + * @details \b Inputs: valveStatus[] + * @details \b Outputs: none + * @param valve ID of valve to get status for + * @return Status for the given valve + *************************************************************************/ +static U08 getValveStatus( VALVE_T valve ) +{ + U08 result = 0; + + if ( valve < NUM_OF_VALVES ) + { + result = getU08OverrideValue( &valveStatus[ valve ] ); + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE4, (U32)valve ) + } + + return result; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Drivers/RotaryValve.h =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Drivers/RotaryValve.h (.../RotaryValve.h) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Drivers/RotaryValve.h (.../RotaryValve.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -35,9 +35,8 @@ #define ROTARY_VALVE_MICROSTEP_FRACTION 8 ///< Rotary valve motors configured for 1/8 step microstepping. #define ROTARY_VALVE_GEAR_RATIO 3.7F ///< Rotary valve motor gear ratio is 3.7:1. -#define ROTARY_VALVE_INIT_FULL_SWING_COUNTS 1880 ///< Rotary valve swing arm travel range is appx. micro steps. -#define ROTARY_VALVE_ENERGIZED_EDGE_MAX_COUNTS 1900 ///< Rotary valve energized edge maximum allowed counts. -#define ROTARY_VALVE_ENERGIZED_EDGE_MIN_COUNTS 1700 ///< Rotary valve energized edge minimum allowed counts. +#define ROTARY_VALVE_INIT_ENERGIZED_COUNTS 2000 ///< Rotary valve target energized edge in counts. +#define ROTARY_VALVE_INIT_DEENERGIZED_COUNTS -200 ///< Rotary valve target de-energized edge in counts. /// rotary pinch valve names typedef enum valveNames @@ -59,6 +58,8 @@ void resetValveEncoder( VALVE_T valve ); void enableValve( VALVE_T valve ); void setValveZeroEncoderPosition( VALVE_T valve ); +void setValveHomingEnableDisable( VALVE_T valve, BOOL enableHoming ); +S16 getValveMaximumEncoderPosition( VALVE_T valve ); BOOL testValveEncoderPositionOverride( MESSAGE_T *message ); BOOL testValveStatusOverride( MESSAGE_T *message ); Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rb824ef4b479578c5aa702abd9147aef505a6fb04 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision b824ef4b479578c5aa702abd9147aef505a6fb04) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -176,6 +176,11 @@ SW_FAULT_ID_VALVES_INVALID_VALVE_ENCODER_REQ = 145, SW_FAULT_ID_TD_VALVES_INVALID_IDLE = 146, SW_FAULT_ID_TD_VALVES_INVALID_IN_TRANSITION = 147, + SW_FAULT_ID_TD_EJECTOR_OPTICAL_SENSOR_INVALID_REQ = 148, + SW_FAULT_ID_VALVES_INVALID_VALVE_HOMING_SET = 149, + SW_FAULT_ID_VALVES_INVALID_VALVE_MAX_ENC_POS_REQ = 150, + SW_FAULT_ID_VALVES_INVALID_VALVE_FINDING_EDGE = 151, + SW_FAULT_ID_TD_VALVES_INVALID_FIND_DEENERGIZED_EDGE = 152, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/FpgaTD.c =================================================================== diff -u -r5eda216f634a74512a5bc11b0984676567512d80 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 5eda216f634a74512a5bc11b0984676567512d80) +++ firmware/App/Services/FpgaTD.c (.../FpgaTD.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-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 FPGA.c +* @file FpgaTD.c * -* @author (last) Sean Nash -* @date (last) 30-Jul-2024 +* @author (last) Dara Navaei +* @date (last) 07-Nov-2025 * * @author (original) Sean Nash -* @date (original) 30-Jul-2024 +* @date (original) 01-Aug-2024 * ***************************************************************************/ Index: firmware/App/Services/FpgaTD.h =================================================================== diff -u -r5eda216f634a74512a5bc11b0984676567512d80 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Services/FpgaTD.h (.../FpgaTD.h) (revision 5eda216f634a74512a5bc11b0984676567512d80) +++ firmware/App/Services/FpgaTD.h (.../FpgaTD.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-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 FPGA.h +* @file FpgaTD.h * -* @author (last) Sean Nash -* @date (last) 30-Jul-2024 +* @author (last) Dara Navaei +* @date (last) 30-Oct-2025 * * @author (original) Sean Nash -* @date (original) 30-Jul-2024 +* @date (original) 01-Aug-2024 * ***************************************************************************/ Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r1500c2a584e9e9ce0ffcd32727c0b9e7cdd141b6 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 1500c2a584e9e9ce0ffcd32727c0b9e7cdd141b6) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision 153784735cd268c81765544a581e36d76067d344) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2024-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-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 Messaging.c * -* @author (last) Sean -* @date (last) 30-Jul-2024 +* @author (last) Dara Navaei +* @date (last) 09-Nov-2025 * -* @author (original) Sean -* @date (original) 30-Jul-2024 +* @author (original) Sean Nash +* @date (original) 01-Aug-2024 * ***************************************************************************/ Index: firmware/App/TDCommon.h =================================================================== diff -u -r77a702e7f5a2524ce04fe0e87b892e10f7ee77d0 -r153784735cd268c81765544a581e36d76067d344 --- firmware/App/TDCommon.h (.../TDCommon.h) (revision 77a702e7f5a2524ce04fe0e87b892e10f7ee77d0) +++ firmware/App/TDCommon.h (.../TDCommon.h) (revision 153784735cd268c81765544a581e36d76067d344) @@ -36,7 +36,7 @@ // #define TEST_PINCH_VALVES 1 // Alpha unit pinch valve testing // #define TEST_DEBUGGER 1 // Testing with debugger - prevents FPGA comm alarms caused by breakpoints // #define TEST_PROCESS_TASKS_WO_UI 1 // Allow task processing even when UI not connected - #define TEST_UI_ONLY 1 // Alpha test with TD and UI only - no DD +// #define TEST_UI_ONLY 1 // Alpha test with TD and UI only - no DD // #define TEST_USE_OFF_AS_STOP_BUTTON 1 // Alpha test re-purposing off button as a stop button #define TEST_NO_PRESSURE_CHECKS 1 // Alpha test with no pressure sensor checks // #define TEST_NO_STOP_CONSUME_CHECK 1 // Alpha test with no check for stop button timeout