Index: eback =================================================================== diff -u --- eback (revision 0) +++ eback (revision 9565d9627edc032a2c6414a38f38f14c62e3ec87) @@ -0,0 +1,132 @@ + LDT-1415-pressures-monitoring-td + LDT-1415-pressures-monitoring-td-updates + LDT-1840-Transmembrane-Pressure-update + LDT-1840-transmembrane-pressure-dialin-updates + LDT-1962-air-infusion + LDT-2240-disposable-tube-set-self-test + LDT-2932-dd-td-TMP-reported-by-Dialin-FW-is-incorrect + LDT-3126-blood-prime-td + LDT-3126-blood-prime-td-updates + LDT-3215-measured-venous-pressure-decreases + LDT-3539-air-infusion-td + LDT-3554-tdpressure-data-is-not-loading + LDT-3910-request-add-td-config-flag-so + LDT-4033-patient-vitals-fw-implementation + LDT-4040-rinseback + LDT-4094-pressures-monitoring-fw-iteration + LDT-4149-pinch-valves-fw-implementation + LDT-4505-td-h4-blood-pump-does-not-run + LDT-4616-air-infusion-fw-iteration-1 + LDT-4727-h12-duty-cycle-reporting + LDT-473 + LDT-473-treatment-parameters-create-rx-- + LDT-473-treatment-parameters-create-rx-beta + LDT-473-treatment-parameters-create-rx-latest + LDT-4809-td-dialin-multiple-td-variable +* LDT-4875-td-h12-is-not-actuating-during + develop + master + staging + remotes/origin/BambooSetup + remotes/origin/HEAD -> origin/master + remotes/origin/LDT-1394-blood-flow-rate-h4-rotor-count + remotes/origin/LDT-1415-pressures-monitoring-td + remotes/origin/LDT-1415-pressures-monitoring-td-2 + remotes/origin/LDT-1415-pressures-monitoring-td-baro + remotes/origin/LDT-1415-pressures-monitoring-td-updates + remotes/origin/LDT-1735-test-config-support-for-dd + remotes/origin/LDT-1840-Transmembrane-Pressure-update + remotes/origin/LDT-1840-transmembrane-pressure-dialin-updates + remotes/origin/LDT-1886-blood-set-auto-load-and-auto-ej + remotes/origin/LDT-1886-blood-set-auto-load-and-auto-eject-implement-ejector-sensor + remotes/origin/LDT-1886-blood-set-auto-load-and-auto-eject-td + remotes/origin/LDT-1903-air-trap-level-control---td---0 + remotes/origin/LDT-1903-air-trap-level-control---td---1 + remotes/origin/LDT-1903-air-trap-level-control-delay-adjust-after-fill-fix---td---0 + remotes/origin/LDT-1903-air-trap-level-control-dev--td---0 + remotes/origin/LDT-1932-td-td-pinch-valves-fail-homing-sequence + remotes/origin/LDT-1962-air-infusion + remotes/origin/LDT-2004-dialysate-composition-drybicart-mixing----dd + remotes/origin/LDT-2043-air-infusion---td + remotes/origin/LDT-2118-main-treatment-screen---td---tel-dev-test + remotes/origin/LDT-2118-main-treatment-screen---td---vectorcast-tests + remotes/origin/LDT-2118-main-treatment-screen---td---vectorcast-tests-2-10-2026 + remotes/origin/LDT-2199-beta-1.0-fw-integration---td-im + remotes/origin/LDT-2240-disposable-tube-set-self-test + remotes/origin/LDT-2340-td-pressure-broadcast-interval- + remotes/origin/LDT-2749-Ability-to-enable-air-bubble-alarm-in-standby-mode + remotes/origin/LDT-2749-ability-to-enable-air-bubble-alarm-fix + remotes/origin/LDT-2932-dd-td-TMP-reported-by-Dialin-FW-is-incorrect + remotes/origin/LDT-3126-blood-prime-td + remotes/origin/LDT-3126-blood-prime-td-updates + remotes/origin/LDT-316-basic-dialysis-treatment---td--- + remotes/origin/LDT-3215-measured-venous-pressure-decreases + remotes/origin/LDT-3236-Reset-Variable-for-air-pump-set-state + remotes/origin/LDT-3259-software-update---td-firmware + remotes/origin/LDT-3505-heparin-td-04-dev-feature-implemenation + remotes/origin/LDT-3539-air-infusion-td + remotes/origin/LDT-3552-the-fw-message-list-generated-are-not-able-to-decode-some-messages + remotes/origin/LDT-3554-tdpressure-data-is-not-loading + remotes/origin/LDT-3559-unable-to-start-treatment-via-d + remotes/origin/LDT-3562-bp-h4-rotor-speed-reads-negativ + remotes/origin/LDT-3599-td-ui-comm-alarms-trigger-after-td-power-on-or-reset + remotes/origin/LDT-3600-request-for-td-test-config-for + remotes/origin/LDT-3722-non-volatile-memory + remotes/origin/LDT-3910-request-add-td-config-flag-so + remotes/origin/LDT-3959-2-blood-flow-rate---fw-implementa + remotes/origin/LDT-3959-blood-flow-rate---fw-implementa + remotes/origin/LDT-3970-edit-treatment-parameters-during-treatment + remotes/origin/LDT-3975-water-treatment-and-degassing-- + remotes/origin/LDT-4002-hdf-fw-implementation + remotes/origin/LDT-4003-hdf-fw-implementation-4-4 + remotes/origin/LDT-4009-isolated-uf-td + remotes/origin/LDT-4013-fluid-bolus + remotes/origin/LDT-4013-fluid-bolus-1 + remotes/origin/LDT-4027-pre-treatment---fw-implementation + remotes/origin/LDT-4028-pre-treatment---fw-implementation + remotes/origin/LDT-4029-pre-treatment---fw-implementation + remotes/origin/LDT-4033-patient-vitals-fw-implementation + remotes/origin/LDT-4040-rinseback + remotes/origin/LDT-4049-standby---fw-implementation---2 + remotes/origin/LDT-4063-power-control-and-post---fw-imp + remotes/origin/LDT-4072-power-loss---fw-implementation- + remotes/origin/LDT-4094-pressures-monitoring-fw-iteration + remotes/origin/LDT-4149-pinch-valves-fw-implementation + remotes/origin/LDT-4188-sw-fw-integration-to-run-a-trea + remotes/origin/LDT-4246-fw-support-for-ui-demo + remotes/origin/LDT-4248-td-ro-loop-testing---demo-td-pi + remotes/origin/LDT-4329-edit-treatment-parameters-during-treatment + remotes/origin/LDT-4494-update-both-h12-scalar-and-duty + remotes/origin/LDT-4505-td-h4-blood-pump-does-not-run + remotes/origin/LDT-4616-air-infusion-fw-iteration-1 + remotes/origin/LDT-469-treatment-parameters-create-rx-- + remotes/origin/LDT-4727-h12-duty-cycle-reporting + remotes/origin/LDT-473-treatment-parameters-create-rx-- + remotes/origin/LDT-473-treatment-parameters-create-rx-beta + remotes/origin/LDT-473-treatment-parameters-create-rx-latest + remotes/origin/LDT-479-treatment-parameters-create-rx-- + remotes/origin/LDT-4809-td-dialin-multiple-td-variable + remotes/origin/LDT-4875-td-h12-is-not-actuating-during + remotes/origin/LDT-736-general-alarm-requirements---td- + remotes/origin/LDT-802-stop-state---td + remotes/origin/LDT-94-main-treatment-screen---implement + remotes/origin/LEAH-103-fw-td-unit-testing + remotes/origin/LEAH-1970-td-integration-changes-1 + remotes/origin/LEAH-282-fw-td-integration-testing + remotes/origin/LEAH-32-fw-td-fpga-interface + remotes/origin/LEAH-39-fw-td-dd-interface + remotes/origin/LEAH-41-fw-td-internal-adc-driver + remotes/origin/LEAH-45-fw-td-bubble-detector-driver-monitor-dev-tests + remotes/origin/LEAH-47-fw-td-buttons-monitor + remotes/origin/LEAH-51-fw-td-blood-pump-controller-moni + remotes/origin/LEAH-57-fw-td-gas-liquid-transfer-pump-driver-dev-tests + remotes/origin/LEAH-60-fw-td-valves-controller-monitor + remotes/origin/LEAH-838-fw-td-gas-liquid-transfer-pump- + remotes/origin/bugfix/LDT-4160-request-get-function-for-full-d + remotes/origin/develop + remotes/origin/feature/LDT-1903-air-trap-level-control---td---0 + remotes/origin/feature/LDT-3259-software-update---td-TEST_REMOVE + remotes/origin/feature/LDT-3959-blood-flow-rate---fw-implementa + remotes/origin/master + remotes/origin/staging + remotes/origin/steve_branch Index: firmware/App/Drivers/PinchValve.c =================================================================== diff -u --- firmware/App/Drivers/PinchValve.c (revision 0) +++ firmware/App/Drivers/PinchValve.c (revision 9565d9627edc032a2c6414a38f38f14c62e3ec87) @@ -0,0 +1,608 @@ +/************************************************************************** +* +* Copyright (c) 2026-2026 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 PinchValve.c +* +* @author (last) Varshini Nagabooshanam +* @date (last) 08-Jul-2026 +* +* @author (original) Varshini Nagabooshanam +* @date (original) 08-Jul-2026 +* +***************************************************************************/ + + +#include "PinchValve.h" +#include "RotaryValve.h" +#include "FpgaTD.h" +#include "Timers.h" +#include "Utilities.h" + +/** + * @addtogroup PinchValve + * @{ + */ + +// ********** private definitions ********** + +#define PINCH_VALVE_FPGA_CMD_START_BIT 0x01 +#define PINCH_VALVE_FPGA_CMD_WRITE_ONLY_BIT 0x02 +#define PINCH_VALVE_FPGA_CMD_TX_WORDS_SHIFT 2 +#define PINCH_VALVE_FPGA_CMD_RX_WORDS_SHIFT 5 +#define PINCH_VALVE_FPGA_CMD_WORD_COUNT_MASK 0x03 + +#define PINCH_VALVE_SPI_CMD_DONE_MASK 0x01 + +#define PINCH_VALVE_ENABLE_BIT 0x01 +#define PINCH_VALVE_RESET_BIT 0x02 + +#define PINCH_VALVE_EXECUTE_DELAY_MS 10 + +#define PINCH_VALVE_NO_WORDS 0 +#define PINCH_VALVE_ONE_WORD 1 +#define PINCH_VALVE_TWO_WORDS 2 +#define PINCH_VALVE_THREE_WORDS 3 + +#define PINCH_VALVE_WRITE_READ_CMD FALSE +#define PINCH_VALVE_WRITE_ONLY_CMD TRUE + +/// Pinch valve driver state machine states. +typedef enum +{ + PINCH_VALVE_IDLE_STATE = 0, ///< Waiting for a new pinch valve command. + PINCH_VALVE_EXECUTE_STATE ///< Executing the active pinch valve command. +} PINCH_VALVE_STATE_T; + +/// Pinch valve execute state machine steps. +typedef enum +{ + PINCH_VALVE_EXECUTE_STEP_WRITE_COMMAND = 0, ///< Write the PMD command to the FPGA. + PINCH_VALVE_EXECUTE_STEP_WAIT_FOR_FPGA, ///< Wait for the FPGA to complete the command transaction. + PINCH_VALVE_EXECUTE_STEP_READ_OUTPUT, ///< Read the command response from the FPGA. + PINCH_VALVE_EXECUTE_STEP_GET_EVENT_STATUS, ///< Read the PMD event status. + PINCH_VALVE_EXECUTE_STEP_GET_ACTIVITY_STATUS, ///< Read the PMD activity status. + PINCH_VALVE_EXECUTE_STEP_GET_ACTUAL_POSITION, ///< Read the PMD actual position. + PINCH_VALVE_EXECUTE_STEP_COMPLETE ///< Complete the current command and return to idle. +} PINCH_VALVE_EXECUTE_STEP_T; + +/// Supported pinch valve command types. +typedef enum +{ + PINCH_VALVE_CMD_TYPE_NONE = 0, ///< No active command. + PINCH_VALVE_CMD_TYPE_HOME, ///< Home the pinch valve. + PINCH_VALVE_CMD_TYPE_POSITION, ///< Move the pinch valve to the requested position. + PINCH_VALVE_CMD_TYPE_READ_STATUS ///< Read the pinch valve status. +} PINCH_VALVE_CMD_TYPE_T; + +/// Pinch valve command execution results. +typedef enum +{ + PINCH_VALVE_CMD_RESULT_IDLE = 0, ///< No command is active. + PINCH_VALVE_CMD_RESULT_BUSY, ///< Command is currently executing. + PINCH_VALVE_CMD_RESULT_COMPLETE, ///< Command completed successfully. + PINCH_VALVE_CMD_RESULT_ERROR ///< Command completed with an error. +} PINCH_VALVE_CMD_RESULT_T; + +/// Pinch valve command information. +typedef struct +{ + VALVE_T valve; ///< Target rotary pinch valve (H1 or H19). + PINCH_VALVE_CMD_TYPE_T cmdType; ///< Command type. + U16 cmdHeader; ///< PMD command header. + U16 inputWord1; ///< PMD command input word 1. + U16 inputWord2; ///< PMD command input word 2. + U16 inputWord3; ///< PMD command input word 3. + U08 txWordCount; ///< Number of words transmitted to the PMD controller. + U08 rxWordCount; ///< Number of words expected from the PMD controller. + BOOL writeOnly; ///< TRUE if the command is write only. + S32 targetPosition; ///< Requested target position. +} PINCH_VALVE_COMMAND_T; + +/// Pinch valve command response. +typedef struct +{ + U16 outputWord1; ///< PMD output word 1. + U16 outputWord2; ///< PMD output word 2. + U16 outputWord3; ///< PMD output word 3. + U08 spiCmdStatus; ///< FPGA SPI command status. + U08 readCount; ///< FPGA read counter. + U08 errorCount; ///< FPGA communication error counter. +} PINCH_VALVE_RESPONSE_T; + + +// ********** private data ********** + +static PINCH_VALVE_STATE_T pinchValveState; +static PINCH_VALVE_EXECUTE_STEP_T executeStep; +static PINCH_VALVE_COMMAND_T activeCommand; +static PINCH_VALVE_RESPONSE_T lastResponse; +static PINCH_VALVE_CMD_RESULT_T commandResult; +static BOOL commandPending; +static U32 executeStartTime; + +// ********** private function prototypes ********** + +static BOOL startPinchValveCommand( PINCH_VALVE_COMMAND_T command ); +static void execIdleState( void ); +static void execExecuteState( void ); + +static void writeCommandToFpga( const PINCH_VALVE_COMMAND_T *command ); +static void readFpgaResponse( VALVE_T valve, PINCH_VALVE_RESPONSE_T *response ); +static void sendStatusReadCommand( VALVE_T valve, U16 commandHeader ); + +static BOOL isFpgaCommandDone( VALVE_T valve ); +static U08 buildFpgaCommandByte( U08 txWordCount, U08 rxWordCount, BOOL writeOnly ); +static void setValveEnableReset( VALVE_T valve, U08 enableReset ); +static void transitionToIdle( PINCH_VALVE_CMD_RESULT_T result ); + + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +void initPinchValve( void ) +{ + pinchValveState = PINCH_VALVE_IDLE_STATE; + executeStep = PINCH_VALVE_EXECUTE_STEP_WRITE_COMMAND; + commandResult = PINCH_VALVE_CMD_RESULT_IDLE; + commandPending = FALSE; + + activeCommand.valve = PINCH_VALVE_H1; + activeCommand.cmdType = PINCH_VALVE_CMD_TYPE_NONE; + activeCommand.cmdHeader = 0; + activeCommand.inputWord1 = 0U; + activeCommand.inputWord2 = 0U; + activeCommand.inputWord3 = 0U; + activeCommand.txWordCount = 0U; + activeCommand.rxWordCount = 0U; + activeCommand.writeOnly = FALSE; + activeCommand.targetPosition = 0; + + lastResponse.outputWord1 = 0U; + lastResponse.outputWord2 = 0U; + lastResponse.outputWord3 = 0U; + lastResponse.spiCmdStatus = 0U; + lastResponse.readCount = 0U; + lastResponse.errorCount = 0U; + + setValveEnableReset( PINCH_VALVE_H1, 0U ); + setValveEnableReset( PINCH_VALVE_H19, 0U ); +} + +/*********************************************************************//** + * @brief Executes the Magellan pinch valve state machine. + * @details \b Inputs: commandPending, pinchValveState + * @details \b Outputs: active command processing and response data + * @return none + *************************************************************************/ +void execPinchValve( void ) +{ + switch ( pinchValveState ) + { + case PINCH_VALVE_IDLE_STATE: + execIdleState(); + break; + + case PINCH_VALVE_EXECUTE_STATE: + execExecuteState(); + break; + + default: + transitionToIdle( PINCH_VALVE_CMD_RESULT_ERROR ); + break; + } +} + +/*********************************************************************//** + * @brief Starts a pinch valve home command. + * @param valve Pinch valve identifier. + * @return TRUE when command was accepted, otherwise FALSE. + *************************************************************************/ +BOOL startPinchValveHome( VALVE_T valve ) +{ + PINCH_VALVE_COMMAND_T command; + + command.valve = valve; + command.cmdType = PINCH_VALVE_CMD_TYPE_HOME; + command.cmdHeader = PINCH_VALVE_PMD_CMD_SET_OPERATING_MODE; + command.inputWord1 = 0x0037U; + command.inputWord2 = 0; + command.inputWord3 = 0; + command.txWordCount = PINCH_VALVE_ONE_WORD; + command.rxWordCount = PINCH_VALVE_NO_WORDS; + command.writeOnly = PINCH_VALVE_WRITE_ONLY_CMD; + command.targetPosition = 0; + + return startPinchValveCommand( command ); +} + +/*********************************************************************//** + * @brief Starts a pinch valve move command. + * @param valve Pinch valve identifier. + * @param targetPosition Target motor position in counts. + * @return TRUE when command was accepted, otherwise FALSE. + *************************************************************************/ +BOOL startPinchValveMove( VALVE_T valve, S32 targetPosition ) +{ + PINCH_VALVE_COMMAND_T command; + + command.valve = valve; + command.cmdType = PINCH_VALVE_CMD_TYPE_POSITION; + command.cmdHeader = PINCH_VALVE_PMD_CMD_SET_POSITION; + command.inputWord1 = (U16)( targetPosition & 0x0000FFFFL ); + command.inputWord2 = (U16)( ( targetPosition >> 16 ) & 0x0000FFFFL ); + command.inputWord3 = 0; + command.txWordCount = PINCH_VALVE_TWO_WORDS; + command.rxWordCount = PINCH_VALVE_NO_WORDS; + command.writeOnly = PINCH_VALVE_WRITE_ONLY_CMD; + command.targetPosition = targetPosition; + + return startPinchValveCommand( command ); +} + +/*********************************************************************//** + * @brief Starts a status read command for the selected pinch valve. + * @param valve Pinch valve identifier. + * @return TRUE when command was accepted, otherwise FALSE. + *************************************************************************/ +BOOL startPinchValveReadStatus( VALVE_T valve ) +{ + PINCH_VALVE_COMMAND_T command; + + command.valve = valve; + command.cmdType = PINCH_VALVE_CMD_TYPE_READ_STATUS; + command.cmdHeader = PINCH_VALVE_PMD_CMD_GET_EVENT_STATUS; + command.inputWord1 = 0U; + command.inputWord2 = 0U; + command.inputWord3 = 0U; + command.txWordCount = PINCH_VALVE_NO_WORDS; + command.rxWordCount = PINCH_VALVE_ONE_WORD; + command.writeOnly = PINCH_VALVE_WRITE_READ_CMD; + command.targetPosition = 0; + + return startPinchValveCommand( command ); +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +PINCH_VALVE_STATE_T getPinchValveState( void ) +{ + return pinchValveState; +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +PINCH_VALVE_CMD_RESULT_T getPinchValveCommandResult( void ) +{ + return commandResult; +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +void getPinchValveResponse( PINCH_VALVE_RESPONSE_T *response ) +{ + if ( response != NULL ) + { + *response = lastResponse; + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static BOOL startPinchValveCommand( PINCH_VALVE_COMMAND_T command ) +{ + BOOL accepted = FALSE; + + if ( ( pinchValveState == PINCH_VALVE_IDLE_STATE ) && ( commandPending == FALSE ) ) + { + activeCommand = command; + commandPending = TRUE; + commandResult = PINCH_VALVE_CMD_RESULT_BUSY; + accepted = TRUE; + } + + return accepted; +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void execIdleState( void ) +{ + if ( commandPending == TRUE ) + { + executeStep = PINCH_VALVE_EXECUTE_STEP_WRITE_COMMAND; + pinchValveState = PINCH_VALVE_EXECUTE_STATE; + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void execExecuteState( void ) +{ + switch ( executeStep ) + { + case PINCH_VALVE_EXECUTE_STEP_WRITE_COMMAND: + { + // Step 1: write command header, input words, and FPGA command. + writeCommandToFpga( &activeCommand ); + executeStartTime = getMSTimerCount(); + executeStep = PINCH_VALVE_EXECUTE_STEP_WAIT_FOR_FPGA; + break; + } + + case PINCH_VALVE_EXECUTE_STEP_WAIT_FOR_FPGA: + { + // Step 2: wait 10 ms before reading FPGA response. + if ( didTimeout( executeStartTime, PINCH_VALVE_EXECUTE_DELAY_MS ) == TRUE ) + { + executeStep = PINCH_VALVE_EXECUTE_STEP_READ_OUTPUT; + } + break; + } + + case PINCH_VALVE_EXECUTE_STEP_READ_OUTPUT: + { + //Step 3: read SPI status and output words. + readFpgaResponse( activeCommand.valve, &lastResponse ); + + if ( isFpgaCommandDone( activeCommand.valve ) == TRUE ) + { + executeStep = PINCH_VALVE_EXECUTE_STEP_GET_EVENT_STATUS; + } + else + { + // FPGA is still busy. Wait before checking again. + executeStartTime = getMSTimerCount(); + executeStep = PINCH_VALVE_EXECUTE_STEP_WAIT_FOR_FPGA; + } + break; + } + + case PINCH_VALVE_EXECUTE_STEP_GET_EVENT_STATUS: + { + // Step 4: request PMD event status. + sendStatusReadCommand( activeCommand.valve, PINCH_VALVE_PMD_CMD_GET_EVENT_STATUS ); + executeStartTime = getMSTimerCount(); + executeStep = PINCH_VALVE_EXECUTE_STEP_GET_ACTIVITY_STATUS; + break; + } + + case PINCH_VALVE_EXECUTE_STEP_GET_ACTIVITY_STATUS: + { + // Step 5: request PMD activity status. + if ( didTimeout( executeStartTime, PINCH_VALVE_EXECUTE_DELAY_MS ) == TRUE ) + { + readFpgaResponse( activeCommand.valve, &lastResponse ); + sendStatusReadCommand( activeCommand.valve, PINCH_VALVE_PMD_CMD_GET_ACTIVITY_STATUS ); + executeStartTime = getMSTimerCount(); + executeStep = PINCH_VALVE_EXECUTE_STEP_GET_ACTUAL_POSITION; + } + break; + } + + case PINCH_VALVE_EXECUTE_STEP_GET_ACTUAL_POSITION: + { + // Step 6: request actual position and read final output. + if ( didTimeout( executeStartTime, PINCH_VALVE_EXECUTE_DELAY_MS ) == TRUE ) + { + readFpgaResponse( activeCommand.valve, &lastResponse ); + sendStatusReadCommand( activeCommand.valve, PINCH_VALVE_PMD_CMD_GET_ACTUAL_POSITION ); + executeStartTime = getMSTimerCount(); + executeStep = PINCH_VALVE_EXECUTE_STEP_COMPLETE; + } + break; + } + + case PINCH_VALVE_EXECUTE_STEP_COMPLETE: + { + // Step 7: read final response and return to Idle. + if ( didTimeout( executeStartTime, PINCH_VALVE_EXECUTE_DELAY_MS ) == TRUE ) + { + readFpgaResponse( activeCommand.valve, &lastResponse ); + transitionToIdle( PINCH_VALVE_CMD_RESULT_COMPLETE ); + } + break; + } + + default: + { + transitionToIdle( PINCH_VALVE_CMD_RESULT_ERROR ); + break; + } + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void writeCommandToFpga( const PINCH_VALVE_COMMAND_T *command ) +{ + U08 fpgaCmd; + + fpgaCmd = buildFpgaCommandByte( command->txWordCount, + command->rxWordCount, + command->writeOnly ); + + if ( command->valve == PINCH_VALVE_H1 ) + { + setH1CmdHeader( command->cmdHeader ); + setH1InputWord1( command->inputWord1 ); + setH1InputWord2( command->inputWord2 ); + setH1InputWord3( command->inputWord3 ); + setH1FPGACmd( fpgaCmd ); + } + else + { + setH19CmdHeader( command->cmdHeader ); + setH19InputWord1( command->inputWord1 ); + setH19InputWord2( command->inputWord2 ); + setH19InputWord3( command->inputWord3 ); + setH19FPGACmd( fpgaCmd ); + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void readFpgaResponse( VALVE_T valve, PINCH_VALVE_RESPONSE_T *response ) +{ + if ( valve == PINCH_VALVE_H1 ) + { + response->spiCmdStatus = getH1SPICmdStatus(); + response->readCount = getH1ReadCount(); + response->errorCount = getH1ErrorCount(); + response->outputWord1 = getH1OutputWord1(); + response->outputWord2 = getH1OutputWord2(); + response->outputWord3 = getH1OutputWord3(); + } + else + { + response->spiCmdStatus = getH19SPICmdStatus(); + response->readCount = getH19ReadCount(); + response->errorCount = getH19ErrorCount(); + response->outputWord1 = getH19OutputWord1(); + response->outputWord2 = getH19OutputWord2(); + response->outputWord3 = getH19OutputWord3(); + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void sendStatusReadCommand( VALVE_T valve, U16 commandHeader ) +{ + PINCH_VALVE_COMMAND_T statusCommand; + + statusCommand.valve = valve; + statusCommand.cmdType = PINCH_VALVE_CMD_TYPE_READ_STATUS; + statusCommand.cmdHeader = commandHeader; + statusCommand.inputWord1 = 0U; + statusCommand.inputWord2 = 0U; + statusCommand.inputWord3 = 0U; + statusCommand.txWordCount = PINCH_VALVE_NO_WORDS; + statusCommand.rxWordCount = PINCH_VALVE_ONE_WORD; + statusCommand.writeOnly = PINCH_VALVE_WRITE_READ_CMD; + statusCommand.targetPosition = 0; + + writeCommandToFpga( &statusCommand ); +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static BOOL isFpgaCommandDone( VALVE_T valve ) +{ + U08 status; + + if ( valve == PINCH_VALVE_H1 ) + { + status = getH1SPICmdStatus(); + } + else + { + status = getH19SPICmdStatus(); + } + + return ( ( status & PINCH_VALVE_SPI_CMD_DONE_MASK ) != 0U ); +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static U08 buildFpgaCommandByte( U08 txWordCount, U08 rxWordCount, BOOL writeOnly ) +{ + U08 fpgaCmd = PINCH_VALVE_FPGA_CMD_START_BIT; + + txWordCount &= PINCH_VALVE_FPGA_CMD_WORD_COUNT_MASK; + rxWordCount &= PINCH_VALVE_FPGA_CMD_WORD_COUNT_MASK; + + if ( writeOnly == TRUE ) + { + fpgaCmd |= PINCH_VALVE_FPGA_CMD_WRITE_ONLY_BIT; + } + + fpgaCmd |= (U08)( txWordCount << PINCH_VALVE_FPGA_CMD_TX_WORDS_SHIFT ); + fpgaCmd |= (U08)( rxWordCount << PINCH_VALVE_FPGA_CMD_RX_WORDS_SHIFT ); + + return fpgaCmd; +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void setValveEnableReset( VALVE_T valve, U08 enableReset ) +{ + if ( valve == PINCH_VALVE_H1 ) + { + setH1EnableReset( enableReset ); + } + else + { + setH19EnableReset( enableReset ); + } +} + +/*********************************************************************//** + * @brief Initializes the Magellan pinch valve driver. + * @details \b Inputs: none + * @details \b Outputs: Pinch valve private state data initialized. + * @return none + *************************************************************************/ +static void transitionToIdle( PINCH_VALVE_CMD_RESULT_T result ) +{ + commandPending = FALSE; + commandResult = result; + executeStep = PINCH_VALVE_EXECUTE_STEP_WRITE_COMMAND; + activeCommand.cmdType = PINCH_VALVE_CMD_TYPE_NONE; + pinchValveState = PINCH_VALVE_IDLE_STATE; +} + +/** @} */ Index: firmware/App/Drivers/PinchValve.h =================================================================== diff -u --- firmware/App/Drivers/PinchValve.h (revision 0) +++ firmware/App/Drivers/PinchValve.h (revision 9565d9627edc032a2c6414a38f38f14c62e3ec87) @@ -0,0 +1,69 @@ +/************************************************************************** +* +* Copyright (c) 2026-2026 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 PinchValve.h +* +* @author (last) Varshini Nagabooshanam +* @date (last) 08-Jul-2026 +* +* @author (original) Varshini Nagabooshanam +* @date (original) 08-Jul-2026 +* +***************************************************************************/ + +#ifndef __PINCHVALVE_H__ +#define __PINCHVALVE_H__ + +#ifndef __PINCH_VALVE_H__ +#define __PINCH_VALVE_H__ + +#include "TDCommon.h" + +/** + * @defgroup PinchValve PinchValve + * @brief Magellan pinch valve driver for H1 and H19. + * + * The PinchValve unit provides a command execution state machine for the + * Magellan based pinch valve interface. FPGA register access is handled by + * FpgaTD. + * + * @addtogroup PinchValve + * @{ + */ + +// ********** public definitions ********** + + + +// PMD IC command codes. +#define PINCH_VALVE_PMD_CMD_SET_PROFILE_MODE 0x00A0 +#define PINCH_VALVE_PMD_CMD_RESET_EVENT_STATUS 0x0034 +#define PINCH_VALVE_PMD_CMD_SET_VELOCITY 0x0011 +#define PINCH_VALVE_PMD_CMD_SET_POSITION 0x0010 +#define PINCH_VALVE_PMD_CMD_UPDATE 0x001A +#define PINCH_VALVE_PMD_CMD_GET_ACTIVITY_STATUS 0x00A6 +#define PINCH_VALVE_PMD_CMD_GET_EVENT_STATUS 0x0031 +#define PINCH_VALVE_PMD_CMD_GET_ACTUAL_POSITION 0x0037 +#define PINCH_VALVE_PMD_CMD_SET_ACTUAL_POSITION 0x004D +#define PINCH_VALVE_PMD_CMD_SET_OPERATING_MODE 0x0065 + +// ********** public function prototypes ********** + +void initPinchValve( void ); +void execPinchValve( void ); + +BOOL startPinchValveHome( PINCH_VALVE_ID_T valve ); +BOOL startPinchValveMove( PINCH_VALVE_ID_T valve, S32 targetPosition ); +BOOL startPinchValveReadStatus( PINCH_VALVE_ID_T valve ); + +PINCH_VALVE_STATE_T getPinchValveState( void ); +PINCH_VALVE_CMD_RESULT_T getPinchValveCommandResult( void ); +void getPinchValveResponse( PINCH_VALVE_RESPONSE_T *response ); + +U16 getPinchValveLastOutputWord3( void ); + +#endif