/**
 * @file  hv_drv_TypecControl.c
 * @brief   Type C layer source file
 *          This file contains functions to UPD hardware for Type C configuration,
 *          TypeC Software State machine.
 * @details This file provides the following functions: \n
 *          (1) \n
 *          (2) \n
 *          (3) \n
 *
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-25
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                         <th>Date         <th>Change Description
 * <tr><td>Hiview SoC Software Team       <td>2022-08-25   <td>init
 * </table>
*/

#include <hv_drv_TypecStdInc.h>

#define TYPEC_DRP_PREFER_SRC
#define TYPEC_SINK_CON_THRE_VAL  0x16
#define TYPEC_RD_THRESHOLD                             0x7F
#define TYPEC_VBUS_DEBOUNCE_MS                         12

#define TYPEC_CC_INT_ONLY_USE_ADC_IN                   1
#define TYPEC_VBUS_ENABLE_DEBOUNCE                     0

#if TYPEC_CC_VOLCHG_USE_POLLING
static UINT8     CC1MatchPre = 0;
static UINT8     CC2MatchPre = 0;
#endif
static UINT16    u16VbusINAPre[2] = {TYPEC_VBUS_THR_VAL_INIT};
static UINT8    DRP_ToggleEN = 0;
static TypeC_CCDebounce_T s_CCDebounce[CONFIG_PD_PORT_COUNT] = {0};
static VOID TypeC_CCUpdateMatchISR(UINT8 u8PortNum);

UINT16 u16aVBUSThrVal[] =    { 640,  2936, 4400, 4400, 4400, 4400};     //0.68V, 3.67V, 5.5V, ,,,

void TypeC_CCDetHandleFunc(UINT8 u8PortNum);

static UINT8 u8GetTypecFSMState(UINT8 u8PortNum)
{
    UINT8 u8Data = SET_TO_ZERO;
    Hv_Typec_RegisterReadISR (u8PortNum, UPD_REG_RO_FSM_STATE, &u8Data, BYTE_LEN_1);
    u8Data &= UPD_FSM_STATE_MASK;
    DEBUG_PRINT_PORT_STR (u8PortNum<<16 | u8Data,"FSM state\r\n");
    return u8Data;
}

VOID Typec_SetFSMState(UINT8 u8PortNum, UINT8 u8State)
{
    UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT);
    u8RegVal &= ~UPD_FSM_CMD_DIRECT_MASK;
    u8RegVal |= u8State;
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, u8RegVal);        //init to force the FSM
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, UPD_FSM_CMD_DIRECT_EN);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, UPD_FSM_CMD_DIRECT_EN);
}

/****************************************************************************************/
/*******************************************************************************************/
/*********************************TypeC Port Initialization**************************************/
/*******************************************************************************************/

#if(HV_TRUE == INCLUDE_PD_DRP)

void TypeC_DRPEnDisToggle(UINT8 u8PortNum, UINT8 u8EnDis)
{
    if (u8EnDis)
    {
        /*Enabling TYPEC_DRP_DONE interrupt*/
        Hv_Typec_RegByteSetBit (u8PortNum, UPD_REG_RW_MISC_IRQMASK, UPD_MISC_DRP_DONE_MASKBIT);
        /*FW sets the DRP Enable (DRP_EN)*/
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_TOGGLE_EN);
        DRP_ToggleEN = 1;
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_DRP_PREFERENCE);
    }
    else
    {
        /*disabling TYPEC_DRP_DONE interrupt*/
        Hv_Typec_RegByteClearBit (u8PortNum, UPD_REG_RW_MISC_IRQMASK, UPD_MISC_DRP_DONE_MASKBIT);
        /*FW sets the DRP Enable (DRP_EN)*/
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_TOGGLE_EN);
        DRP_ToggleEN = 0;
    }
}

void TypeC_DRPInitHT7315(void)
{
    /* HT7315 DRP Setting Start */

    HV_W32_FIELD(STANDBY_USB_TYPEC_1_00_90, REG_00_RW_2D91_TRIM_INITIAL, 0x18);

    /* for ADC jitter */
    HV_W32_FIELD(STANDBY_USB_TYPEC_1_00_B0, REG_00_RW_2DB0_reg_cc_chg_cnt, 0xFF);
    HV_W32_FIELD(STANDBY_USB_TYPEC_PHY_TOP_00_00, reg_00_ccphy_divsel, 0x0);

    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_04, reg_00_cc1_rd_en, 0x1);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_04, reg_00_cc2_rd_en, 0x1);

    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_10, reg_00_vbus_off_thd, 0x24);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_14, reg_00_vconn_on_thd, 0xF0);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_14, reg_00_vconn_off_thd, 0xC8);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_18, reg_00_vsink_disconnect_vol, 0x3C);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_18, reg_00_vsink_disconnect_pd_vol, 0x28);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_18, reg_00_vsafe0v, 0x6);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_18, reg_00_vvconn_disconnect_vol, 0x3C);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_1C, reg_00_vvconn_discharge_vol, 0x3C);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_1C, reg_00_vrd_usb_vol, 0x14);

    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_20, reg_00_sink_con_threshold, TYPEC_SINK_CON_THRE_VAL);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_28, reg_00_typec_vbus_sel, 0x1);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_34, reg_00_tdrp, 0x4B);
    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_34, reg_00_dcsrc_drp, 0xC0/* 0x80 */);

    HV_W32_FIELD(STANDBY_USB_TYPEC_PHY_TOP_00_04, reg_00_ccphy_rptrim, 0x36);

    HV_W32_FIELD(STANDBY_USB_TYPEC_PHY_TOP_00_00, reg_00_ccphy_ccrxvrefh, 0x64);
    HV_W32_FIELD(STANDBY_USB_TYPEC_PHY_TOP_00_00, reg_00_ccphy_ccrxvrefl, 0x50);

    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_AC, reg_00_delta, 0x6);
    HV_W32_FIELD(STANDBY_USB_TYPEC_1_00_0C, reg_00_PREDISCTX, 0x3);

    HV_W32_FIELD(STANDBY_USB_TYPEC_TOP_00_AC, reg_00_discard, 0x0);

    /* HT7315 DRP Setting End */
}

void TypeC_InitDRPPort (UINT8 u8PortNum)
{
    UINT16 u16Data;

    /*Setting CC Comparator OFF*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

    /*Setting VBUS Comparator OFF*/
    TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

    u16Data = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);
    TypeC_DRPSetCCSampleEnable (u8PortNum, u16Data);

    Hv_Typec_RegWriteWord(u8PortNum, UPD_CC_DRP_DELAY_CNT, 300000);

    /*Clear Rp value in u8PortSts*/
    gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;

    /*set drp time*/
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TDRP, 80);        //temp 80ms
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_DCSRC_DRP, 120);

#ifdef TYPEC_DRP_PREFER_SRC
    /*drp preference - SRC*/
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_DRP_PREFERENCE);
#else
    /*drp preference - SNK*/
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_DRP_PREFERENCE);
#endif
    /*drp try src support*/
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CONFIG_HIGH, UPD_CONFIG_HIGH_TRY_SRC_SUPPORT);

    /*drp try sink support*/
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CONFIG_HIGH, UPD_CONFIG_HIGH_TRY_SINK_SUPPORT);

    /*power role sel for rp/rd det in design*/
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_EXTEN_CTRL1, UPD_EXTEN_CTRL1_PWR_ROLE_SEL);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG, 0x41);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_SINK_CON_TH, TYPEC_SINK_CON_THRE_VAL);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RA_THRD, TYPEC_CC_THR3_VAL);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RD_THRD, TYPEC_RD_THRESHOLD); // TYPEC_CC_THR6_VAL

    /*Setting the VBUS to vSafe0V before entering the Source State machine*/
    DPM_DriveVBUS (u8PortNum, DPM_VBUS_OFF);

    TypeC_SetCCDeviceRole (u8PortNum, PD_ROLE_DRP);
    gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_DRP;

#if (HV_TRUE == INCLUDE_PD_DRP_TOGGLING)
    UINT8 u8Data = SET_TO_ZERO;
    /*Get the state being advertised from DRP_CTL_HIGH register*/
    Hv_Typec_RegisterReadISR (u8PortNum, UPD_REG_RO_FSM_STATE, &u8Data, BYTE_LEN_1);
    DEBUG_PRINT_PORT_STR (u8Data & UPD_FSM_STATE_MASK,"fm state\r\n");

    gasTypeCcontrol[u8PortNum].u8TypeCState = (UINT8)TYPEC_UNATTACHED_SRC;
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_WAIT_DRPDONE_SS;

    Typec_SetFSMState(u8PortNum, TYPEC_FSM_STATE_UNATTACHED_SOURCE);

    TypeC_DRPEnDisToggle(u8PortNum, HV_TRUE);
#else
    //DPM_UpdatePowerRole (u8PortNum, PD_ROLE_SOURCE);
    //DPM_UpdateDataRole (u8PortNum, PD_ROLE_DFP);
    DPM_UpdatePowerRole (u8PortNum, PD_ROLE_SINK);
    DPM_UpdateDataRole (u8PortNum, PD_ROLE_UFP);
    gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_INIT;
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = SET_TO_ZERO;
#endif

    TypeC_DRPInitHT7315();

    /* Notify external DPM of DRP Port enabled event through a user defined call back*/
    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_PORT_ENABLED);

    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: DRP Port Init Done\r\n");
}

void TypeC_ResetDRPPort(UINT8 u8PortNum)
{
    TypeC_InitDRPPort(u8PortNum);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
}

#endif
/**************************************************************************************/
void TypeC_InitPort (UINT8 u8PortNum)
{
    /*Setting CC Comparator OFF*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

    /*Setting VBUS Comparator OFF*/
    TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

    /*Enabling the CC Interrupts in CC_INT_EN register (TYPEC_CC_MATCH_VLD, TYPEC_CC1_MATCH_CHG and
    TYPEC_CC2_MATCH_CHG interrupt)*/
    //the intterrupt is included in ConfigCCComp

    /* Setting VSinkDisconnect value in VBUS THR0*/
    //Hv_Typec_RegWriteWord (u8PortNum, TYPEC_VBUS_THR0,
    //  (UINT16)((float)TYPEC_VSINKDISCONNECT_THR * gasTypeCcontrol[u8PortNum].fVBUSCorrectionFactor));
    u16aVBUSThrVal[1] = (UINT16)TYPEC_VSINKDISCONNECT_THR;
#if (HV_TYPEC_CONFIG_TYPEC_MODE != TYPEC_MODE_SINK)
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VSINK_DISCONNECT_TH, TYPEC_SET_VBUS_TH_TO_REG_TH(TYPEC_VSINKDISCONNECT_THR));
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_OFF_TH, TYPEC_SET_VBUS_TH_TO_REG_TH(TYPEC_VSINKDISCONNECT_THR));
#else
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VSINK_DISCONNECT_TH, 0x3C);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VSINK_DISCONNECT_PD_TH, 0x28);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_OFF_TH, TYPEC_SET_VBUS_TH_TO_REG_TH(TYPEC_VSINKDISCONNECT_THR));
#endif

    // use hardware detect cable flip
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG, UPD_CC_SEL_PLUG_MASK | UPD_PLUG_APP_MODE_MASK);

    DEBUG_PRINT_PORT_STR (DPM_GET_CURRENT_POWER_ROLE(u8PortNum), "current power role\r\n");
    switch (DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {

#if (HV_TRUE == INCLUDE_PD_SOURCE)
        case PD_ROLE_SOURCE:
        {
            /*Write CCx Debounce clear enable register, CCx Match Enable register,
            CCx sample enable register*/
            TypeC_SetCCDebounceVariable (u8PortNum, DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum));

#if (HV_FALSE == INCLUDE_PD_DRP)
            /*Setting Port Role as DFP in TYPEC_CC_HW_CTL register*/
            TypeC_SetCCDeviceRole (u8PortNum, PD_ROLE_DFP);
#endif

            /* Clear TypeC Current Rp Val bits in u8PortSts*/
            gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;

            /*Setting Rp Current Source as user given and Rd as Open disconnect in both CC1 and
            CC2*/
            UINT16 u16Data = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);

            /*Setting the Power role as Source*/
            TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, (UINT8) u16Data, TYPEC_ENABLE_CC1_CC2);

            /*Setting the Current Rp value status in u8PortSts variable as user given Rp value*/
            gasTypeCcontrol[u8PortNum].u8PortSts |= (u16Data << TYPEC_CURR_RPVAL_POS);

            /* If Typec hw state is UPD_FSM_STATE_ATTACHED_SRC, just to do TYPEC_ATTACHED_SRC_DRIVE_PWR_SS */
            if (UPD_FSM_STATE_ATTACHED_SRC == u8GetTypecFSMState(u8PortNum))
            {
                DPM_SetTypeCState (u8PortNum, TYPEC_ATTACHED_SRC, TYPEC_ATTACHED_SRC_DRIVE_PWR_SS);

                if (ePE_SRC_STARTUP != gasPolicyEngine[u8PortNum].ePEState)
                {
                    /* Kill all the port timers */
                    PDTimer_KillPortTimers(u8PortNum);
                    gasPolicyEngine[u8PortNum].u8PETimerID = MAX_CONCURRENT_TIMERS;
                    gasPolicyEngine[u8PortNum].ePEState = ePE_SRC_STARTUP;
                    gasPolicyEngine[u8PortNum].ePESubState = ePE_SRC_STARTUP_ENTRY_SS;
                    gasPolicyEngine[u8PortNum].u8HardResetCounter = RESET_TO_ZERO;
                }
            }
            else
            {
                /*Setting the Initial State and Sub state for Source*/
                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SRC;
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_INIT_VSAFE0V_SS;

                Typec_SetFSMState(u8PortNum, TYPEC_FSM_STATE_UNATTACHED_SOURCE);
            }
            break;
        }

#endif /*INCLUDE_PD_SOURCE*/

#if (HV_TRUE == INCLUDE_PD_SINK)
        case PD_ROLE_SINK:
        {
            /*set CC match value*/
            TypeC_SetCCDebounceVariable (u8PortNum, TYPEC_UFP);

#if (HV_FALSE == INCLUDE_PD_DRP)
            /*Setting Port Role as UFP in TYPEC_CC_HW_CTL register */
            TypeC_SetCCDeviceRole (u8PortNum, PD_ROLE_UFP);
#endif

            if (HV_FALSE == (gasCfgStatusData.sPerPortData[u8PortNum].u32ClientRequest &
                             DPM_CLIENT_REQ_PORT_DISABLE))            //select init with disable by user
            {
                /*Setting the Rd Value */
                TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1_CC2);


#if(HV_TRUE == INCLUDE_PD_DRP && HV_TRUE == INCLUDE_PD_DRP_TOGGLING)
                /*Setting the Initial State and Sub-state for Sink*/
                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHWAIT_SNK;
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_ENTRY_SS;
#else
                /*Setting the Initial State and Sub-state for Sink*/
                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SNK;
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;

                Typec_SetFSMState(u8PortNum, TYPEC_FSM_STATE_UNATTACHED_SINK);
#endif
            }
            else
            {
                //to add how to enter the disable

                /*Setting the CC1 and CC2 line as Open Disconnect*/
                TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_OPEN_DIS, TYPEC_ENABLE_CC1_CC2);

                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_DISABLED;
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_ENTRY_SS;

                /* Change Policy Engine state and sub-state to invalid state */
                gasPolicyEngine[u8PortNum].ePEState = ePE_INVALIDSTATE;
                gasPolicyEngine[u8PortNum].ePESubState = ePE_INVALIDSUBSTATE;

                //cmd dirct to add
            }
            break;
        }

#endif/*INCLUDE_PD_SINK*/

        default:
            break;
    }

#if(HV_TRUE == INCLUDE_PD_DRP && HV_TRUE == INCLUDE_PD_DRP_TOGGLING)
    /*Disable DRP offload.*/
    TypeC_DRPEnDisToggle(u8PortNum, HV_FALSE);
#endif

    /*Setting CC Comparator ON*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);

    /*Setting the Power Module as per the port role*/
    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        /*Setting the VBUS to vSafe0V before entering the State machine*/
#if (HV_TRUE == INCLUDE_PD_SOURCE)
        DPM_DriveVBUS (u8PortNum, DPM_VBUS_OFF);
#endif
    }
    else
    {
        /*Disable the Sink circuitry to stop sinking the power from source*/
#if (HV_TRUE == INCLUDE_PD_SINK)
        // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
        // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);
#endif
    }
    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: Port Init Done\r\n");

}

void TypeC_GenericInitPort (UINT8 u8PortNum)
{
    /*reset*/
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_PERI);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_PERI);

#if (HV_TYPEC_CONFIG_TYPEC_MODE != TYPEC_MODE_SINK)


    /*Setting IP clk */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_MODULE_CLOCK, 0x80); /* 0xC0 is wrong, bit14 = 0 for rx clock enable */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_FSM_CLK, 0xF0);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CLK_FREQ, 27);

    //phy TRIM_INITIAL
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_TYPEC_TRIM_INITIAL, 0x0C);

    /* set sleep mode off */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_PHY_SLEEP_MODE, 0x03);

    /* Set vbus sel from typec vbus */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_TYPEC_VBUS_SEL, UPD_TYPEC_VBUS_SEL_MASK);

    Hv_Typec_RegByteClearBit(u8PortNum, UPD_CC_RP_EN_DRP_ROLE, UPD_CC_PREN_DRP_NOREALCHIP);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_CC_RP_EN_DRP_ROLE, UPD_CC_PREN_DRP_REALCHIP);

    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_CHIP_CONFIG, UPD_CC0_DET_2BIT_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_CHIP_CONFIG, UPD_CC1_DET_2BIT_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_SW_CONFIG, UPD_SW_CTRL_RD_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_SW_CONFIG, UPD_SW_CTRL_RP_EN);

    /* Self power enable */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_SELF_POWERED);
    /* CC1 and CC2 no VCONN source default */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_VCONN_SEL, (UPD_VCONN_CC1_SEL | UPD_VCONN_CC2_SEL));
    /* Set VBUS and VCONN power detection configuration */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_VCONN_CONFIG, 0xA3);

    /*Setting the default threshold values in VBUS VSAFE0V Threshold register*/
    u16aVBUSThrVal[0] = TYPEC_VSAFE0V_VBUS_THR;
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VSAFE0V_TH, (TYPEC_SET_VBUS_TH_TO_REG_TH(TYPEC_VSAFE0V_VBUS_THR) + 6));

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_ON_TH, 45);     // fix 5V
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VCONN_ON_TH, TYPEC_CC_ADC_THR_IN_UNIT(3700));
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VCONN_OFF_TH, TYPEC_CC_ADC_THR_IN_UNIT(3300));
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VVCONN_DISCONNECT_TH, TYPEC_CC_ADC_THR_IN_UNIT(2400));      //max 2.4V, min 800mv
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VVCONN_DISCHARGE_TH, TYPEC_CC_ADC_THR_IN_UNIT(800));        //max 800mv
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VRD_USB_TH, TYPEC_CC_ADC_THR_IN_UNIT(250));         //min 0.25V

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_CHG_CNT, 0xB0);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_CHG_THD, 0x0A);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_ADC_IN_DB, 0x0F);

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TCCDEBOUNCE, 150);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TPDDEBOUNCE, 15);        //must be grather than the drp delay cnt.
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TTRYCCDEBOUNCE, 15);
#else
    /*Setting IP clk */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_MODULE_CLOCK, 0x80); /* 0xC0 is wrong, bit14 = 0 for rx clock enable */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_FSM_CLK, 0xF0);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CLK_FREQ, 27);

    //phy TRIM_INITIAL
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_TYPEC_TRIM_INITIAL, 0x18);

    /* set sleep mode off */
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_PHY_SLEEP_MODE, 0x03);

    /* Set vbus sel from typec vbus */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_TYPEC_VBUS_SEL, UPD_TYPEC_VBUS_SEL_MASK);

    Hv_Typec_RegByteClearBit(u8PortNum, UPD_CC_RP_EN_DRP_ROLE, UPD_CC_PREN_DRP_NOREALCHIP);
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_CC_RP_EN_DRP_ROLE, UPD_CC_PREN_DRP_REALCHIP);

    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_CHIP_CONFIG, UPD_CC0_DET_2BIT_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_CHIP_CONFIG, UPD_CC1_DET_2BIT_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_SW_CONFIG, UPD_SW_CTRL_RD_EN);
    Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_CC_SW_CONFIG, UPD_SW_CTRL_RP_EN);

    /* Self power enable */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_SELF_POWERED);
    /* CC1 and CC2 no VCONN source default */
    Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_VCONN_SEL, (UPD_VCONN_CC1_SEL | UPD_VCONN_CC2_SEL));

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_VCONN_CONFIG, 0xA3);

    u16aVBUSThrVal[0] = TYPEC_VSAFE0V_VBUS_THR;
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VSAFE0V_TH, 0x6);

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RA_THRD, 0x20);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RD_THRD, 0xA6);

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VBUS_ON_TH, 0x2F);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VCONN_ON_TH, 0xF0);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VCONN_OFF_TH, 0xC8);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VVCONN_DISCONNECT_TH, 0x3C);      //max 2.4V, min 800mv
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VVCONN_DISCHARGE_TH, 0x3C);        //max 800mv
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_VRD_USB_TH, 0x14);         //min 0.25V

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_CHG_CNT, 0xC8);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_CHG_THD, 0x0A);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_ADC_IN_DB, 0x0F);

    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TCCDEBOUNCE, 150);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TPDDEBOUNCE, 15);        //must be grather than the drp delay cnt.
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_TTRYCCDEBOUNCE, 15);
#endif
}
/*******************************************************************************************/
/*********************************TypeC State machine**************************************/
/*******************************************************************************************/

#if(HV_TRUE == INCLUDE_PD_DRP)
static BOOL bDrpToggleFlag = HV_FALSE;
#endif
static UINT8 su8FSM_State_pre = 0;

void TypeC_RunStateMachine (UINT8 u8PortNum)
{
    UINT8 u8CC1MatchISR = SET_TO_ZERO;
#if (HV_TRUE == INCLUDE_PD_SOURCE)
    UINT8 u8CC2MatchISR  = SET_TO_ZERO;
#endif

    UINT8 u8IntStsISR = SET_TO_ZERO;

    /*Handle CC and DRP Interrupt if any*/
    TypeC_CCDRPIntrHandler (u8PortNum);

    HV_PSF_HOOK_DISABLE_GLOBAL_INTERRUPT();

    u8CC1MatchISR = gasTypeCcontrol[u8PortNum].u8CC1MatchISR;
#if (HV_TRUE == INCLUDE_PD_SOURCE)
    u8CC2MatchISR = gasTypeCcontrol[u8PortNum].u8CC2MatchISR;
#endif

    u8IntStsISR = gasTypeCcontrol[u8PortNum].u8IntStsISR;

    HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();

    UINT8 u8FSM_State = 0;
    u8FSM_State = Hv_Typec_RegReadByte(u8PortNum, 0x024c);
    if (u8FSM_State != su8FSM_State_pre && !DRP_ToggleEN)
    {
        su8FSM_State_pre = u8FSM_State;
        DEBUG_PRINT_PORT_STR (u8FSM_State, "#### typec hw fsm ####\r\n");
    }
    if (u8FSM_State == 9)
    {
#if(HV_TRUE == INCLUDE_PD_DRP)
        if (DRP_ToggleEN == 0)
        {
            TypeC_DRPEnDisToggle(u8PortNum, HV_TRUE);
            PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);
            PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_TRUE);
        }
#endif
    }

    switch (gasTypeCcontrol[u8PortNum].u8TypeCState)
    {
        case TYPEC_INIT:
        {
            TypeC_InitPort (u8PortNum);

            PRL_UpdatePowerRole (u8PortNum);

            break;
        }
            /*-----------------------------------------TypeC Source States------------------------------*/
#if (HV_TRUE == INCLUDE_PD_SOURCE)

        case TYPEC_UNATTACHED_SRC:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
#if(HV_TRUE == INCLUDE_PD_DRP)
                case TYPEC_UNATTACHED_SRC_WAIT_DRPDONE_SS:
                {
                    /*Wait here initially until a partner is found*/
                    if (DPM_GET_CURRENT_POWER_ROLE(u8PortNum) != PD_ROLE_DRP)
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_INIT_VSAFE0V_SS;
                    }
                    break;
                }
#endif
                case TYPEC_UNATTACHED_SRC_INIT_VSAFE0V_SS:
                {
                    /* Check for VBUS VSafe0V for Voltage driven in TypeC Initialization */
                    if (TYPEC_VSAFE_0V_MATCH_VAL == gasTypeCcontrol[u8PortNum].u8VbusMatchISR)
                    {
                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_UNATTACHED_SRC_INIT_VSAFE0V_SS\r\n");

                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
                    }
                    else
                    {
                        /* Hook to notify PE state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE(u8PortNum, eIDLE_TYPEC_NOTIFY);
                        //VbusMatchPre = gasTypeCcontrol[u8PortNum].u8VbusMatchISR;
                    }
                    break;
                }

                case TYPEC_UNATTACHED_SRC_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (gasTypeCcontrol[u8PortNum].u8TypeC_CCCompSta, "TYPEC_UNATTACHED_SRC_ENTRY_SS\r\n");

                    /* In altermode, after reboot phone or notebook, MUST trigger VDM after attach again. */
                    DPM_UpdateDataRole (u8PortNum, PD_ROLE_DFP);

                    /* Disable the receiver*/
                    PRL_EnableRx (u8PortNum, HV_FALSE);

                    /*Check whether the current Rp value is same as the default Rp value*/
                    if (((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_CURR_RPVAL_MASK) \
                            >> TYPEC_CURR_RPVAL_POS) != DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum))
                    {
                        /*Power down the CC comparator*/
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                        /*Setting the user given Rp value since it is changed by collision
                        avoidance*/
                        TypeC_SetCCDefaultRpValue (u8PortNum);

                        /*Set the CC Comparator to sample both CC1 and CC2*/
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);

                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: RP Value of Source set to"\
                                              "User given Value\r\n");
                    }

#if(HV_TRUE == INCLUDE_PD_DRP && HV_TRUE == INCLUDE_PD_DRP_TOGGLING)

                    /*refresh the CC status after DRP done*/
                    TypeC_CCDetHandleFunc(u8PortNum);

                    /*Disable DC_DC_EN if DRP does not act as source*/
                    PWRCTRL_ConfigDCDCEn (u8PortNum, HV_FALSE);

                    if ((PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum)) && \
                            (PD_ROLE_DRP != gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState))
                    {
                        /*Setting CC Comparator OFF*/
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                        DEBUG_PRINT_PORT_STR (gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState, "u8DRPLastAttachedState\r\n");
                        if (PD_ROLE_SOURCE == gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState)
                        {
                            TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1_CC2);

                            gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SNK;
                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;
                        }
                        else if (PD_ROLE_SINK == gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState)
                        {
                            gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_DRP;

                            /*Set power and data role status*/
                            DPM_UpdatePowerRole (u8PortNum, PD_ROLE_DRP);
                            DPM_UpdateDataRole (u8PortNum, PD_ROLE_TOGGLING);

                            /*Enable DRP offload.*/
                            TypeC_DRPEnDisToggle(u8PortNum, HV_TRUE);

                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_INIT_SS;
                        }
                        // else
                        // {
                            /* Do Nothing */
                        // }
                    }
                    else
#endif
                    {

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_INIT_SS;
#if (HV_TYPEC_CONFIG_TYPEC_MODE == TYPEC_MODE_SRC)
                    /*refresh the CC status after DRP done*/
                        TypeC_CCDetHandleFunc(u8PortNum);
#endif
                        TypeC_SrcIntrHandler(u8PortNum);
                    }

                    break;
                }

                case TYPEC_UNATTACHED_SRC_INIT_SS:
                {
                    /*DPM power fault handler resets SM by polling this state
                     TYPEC_UNATTACHED_SRC_INIT_SS in the handler for Src unattach.
                     Any module can reset its SM by polling this state*/
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_IDLE_SS;

                    /* Notify external DPM of Port enabled event through a user defined call back*/
                    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_PORT_ENABLED);

                    /* Notify external DPM of Type C Detach event through a user defined call back*/
                    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_DETACH_EVENT);

                    break;
                }

                /*Source waits in this sub-state for sink attachment*/
                case TYPEC_UNATTACHED_SRC_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_ATTACHWAIT_SRC:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                /*This SubState is used to start a tCCDebounce timer for Sink attachment*/
                case TYPEC_ATTACHWAIT_SRC_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHWAIT_SRC_ENTRY_SS\r\n");
#if(HV_TRUE == INCLUDE_PD_DRP)
                    if (PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum))
                    {
                        gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SOURCE;
                        /*Enable DC_DC_EN if DRP acts as source*/
                        /*For configurations other than DRP, DC_DC_EN is high by default*/
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_TRUE);
                    }
#endif
                    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                            (TYPEC_TCCDEBOUNCE_TIMEOUT_MS), \
                            TypeC_SubStateChange_TimerCB, u8PortNum, \
                            TYPEC_ATTACHWAIT_SRC_CC_DEB_TIMEOUT_SS);

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHWAIT_SRC_IDLE_SS;

                    break;
                }

                /*Source waits in this sub-state until the tCCDebounce timer timeouts*/
                case TYPEC_ATTACHWAIT_SRC_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                /*Source enters this sub-state after the tCCDebounce timer timeouts*/
                case TYPEC_ATTACHWAIT_SRC_CC_DEB_TIMEOUT_SS:
                {
                    /*VBUS should be at vSafe0V before transition to AttachedSRC State*/
                    /*Check for VBUS Absence before moving to Attached SRC state */
                    // if (TYPEC_VBUS_0V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /* Turn off VBUS Discharge */
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        if (u8CC1MatchISR == u8CC2MatchISR)
                        {
                            /*Ra is present on both CC lines*/
                            if (u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCDebMatch)
                            {
                                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_AUDIO_ACCESSORY;
                            }
                            /*Rd is present on both CC lines*/
                            else
                            {
                                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNORIENTED_DEBUG_ACCESSORY_SRC;
                            }
                        }
                        /*Rd is present on either CC1 or CC2 line and Ra may be present on either CC1 or CC2 line*/
                        else
                        {
                            gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHED_SRC;
                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_DRIVE_PWR_SS;
                        }
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_ATTACHED_SRC:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                /* This sub-state will be entered from
                   Attached Sink state during Sink to Source PR_Swap/FR_Swap */
                case TYPEC_ATTACHED_SRC_SWAP_ASSERT_RP_SS:
                {
                    /* Initial Source would have turned off VBUS.
                       Before placing Rp, check if VBUS is at 0V */
                    UINT8 u8VBUSValueToCheck;

                    /*If DPM_IS_FRS_XMT_OR_DET_ENABLED returns HV_TRUE, and a swap is in progress,
                      the swap is an FR_Swap. */
                    if (HV_TRUE == DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))
                    {
                        u8VBUSValueToCheck = TYPEC_VBUS_5V_PRES;
                    }
                    else
                    {
                        u8VBUSValueToCheck = TYPEC_VBUS_0V_PRES;
                    }

                    // if (u8VBUSValueToCheck == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SRC_SWAP_ASSERT_RP_SS\r\n");

                        /*force the design FSM from snk.attach trans to src.attach.*/
                        TypeC_DRPSetPRSwapPsRdy(u8PortNum, HV_TRUE);

                        gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SOURCE;

                        /* Disable VBUS Discharge which would have been
                           enabled while detecting TYPEC_MAX_VSAFE_0V_VAL */
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        /* Set the Port Power role variable as Source, so that
                           moving forward all the APIs would act upon the new power role */
                        DPM_UpdatePowerRole (u8PortNum, PD_ROLE_SOURCE);

                        /* Enable DC_DC_EN pin for Source functionality */
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_TRUE);

                        /* CC Comparator would have been turned off in
                         TYPEC_ATTACHED_SNK_SWAP_TRANS_TO_SRC_SS sub-state. No need
                         to do it here once again */
                        /* Configure the device role as DFP for the
                           UPD350 to act as Source */
                        //TypeC_SetCCDeviceRole (u8PortNum, PD_ROLE_DFP);
                        /* Get Rp value from user configuration */
                        UINT8 u8Data = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);
                        /*Set the u8CCDebMatch and u8CCSrcSnkMatch variable accordingly as per Rp Value*/
                        TypeC_SetCCDebounceVariable (u8PortNum, u8Data);

                        /* When transitioning to Source, it is needed to detect the presence
                           of powered cable. So, irrespective of whether the port is VCONN
                           Source or not, enable CC Debounce thresholds on both the CC pins */
                        /*Reset the CC Debounce clear enable,CC Match Enable,CC Sample Enable register*/
                        TypeC_SetCCSampleEnable (u8PortNum, TYPEC_ENABLE_CC1_CC2);

                        /* Turn on the CC Comparator */
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);

                        /*need update the cc status, because the cc status has been stable*/
                        TypeC_CCDetHandleFunc(u8PortNum);
                        TypeC_SrcIntrHandler(u8PortNum);

                        /* Wait for CC RD match valid interrupt */
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_SWAP_RD_PRES_DETECT_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }
                /* Source waits in this sub-state to detect the presence of Sink */
                case TYPEC_ATTACHED_SRC_SWAP_RD_PRES_DETECT_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }
#endif
                /*Source Drives VBUS and VCONN required in this sub-state*/
                case TYPEC_ATTACHED_SRC_DRIVE_PWR_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SRC_DRIVE_PWR_SS\r\n");

                    /*Kill the TYPEC_TCCDEBOUNCE_TIMEOUT_MS timer if exist */
                    TypeC_KillTypeCTimer (u8PortNum);

                    gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SOURCE;

                    
                    TypeC_CCDetHandleFunc(u8PortNum);
                    TypeC_UpdatePwdCableStatus(u8PortNum);

                    /* Drive VBus for vSafe5V */
                    DPM_DriveVBUS (u8PortNum, DPM_VBUS_ON);

                    /*Start the VBUS ON timer for monitoring the time taken for
                    power module to reach vSafe5V*/
                    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start (
                                (TYPEC_VBUS_ON_TIMER_MS),
                                DPM_VBUSOnOffOrVCONNOff_TimerCB, u8PortNum,
                                (UINT8)SET_TO_ZERO);

#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_ON)
                    /*Enable VCONN FETs if Powered cable is present. Do not
                      disturb VCONN when a PR_Swap/FR_Swap is in progress */
                    if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_PWDCABLE_PRES_MASK) &&
                            (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)))
                    {
                        /*Enable VCONN for powered cable attached in CC1 or CC2 line */
                        TypeC_EnabDisVCONN (u8PortNum, TYPEC_VCONN_ENABLE);

                        /* Set VCONN Source Responsibility status */
                        DPM_SET_VCONN_SRC_RESPONSIBILITY(u8PortNum);
                    }
#endif
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_WAIT_FOR_VBUS_ON_SS;

                    break;
                }

                case TYPEC_ATTACHED_SRC_WAIT_FOR_VBUS_ON_SS:
                {
                    if (TYPEC_VBUS_5V == DPM_GetVBUSVoltage(u8PortNum))
                    // if (TYPEC_VBUS_5V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    {
                        DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC_ATTACHED_SRC_WAIT_FOR_VBUS_ON_SS\r\n");
                        /*Kill the VBUS ON timer since vSafe5V is reached*/
                        TypeC_KillTypeCTimer (u8PortNum);

#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_ON)
                        if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_PWDCABLE_PRES_MASK)
                                && (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)))
                        {
                            /*Start the VCONN ON timer for monitoring the time taken for
                            VCONN to reach its Min value*/
                            /*Failure to reach the VCONN Min will result in Error Recovery state*/

                            gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start (
                                        TYPEC_VCONNON_TIMEOUT_MS,
                                        DPM_VCONNONError_TimerCB, u8PortNum,
                                        (UINT8)SET_TO_ZERO);

                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_WAIT_FOR_VCONN_ON_SS;
                        }
                        else
#endif
                        {
                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_SET_PRL_SS;
                        }
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                case TYPEC_ATTACHED_SRC_WAIT_FOR_VCONN_ON_SS:
                {

                    if (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK)
                    {
                        DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC_ATTACHED_SRC_WAIT_FOR_VCONN_ON_SS\r\n");

                        /*Kill the VCONN ON timer since VCONN is turned ON*/
                        TypeC_KillTypeCTimer (u8PortNum);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_SET_PRL_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                case TYPEC_ATTACHED_SRC_SET_PRL_SS:
                {
                    DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC_ATTACHED_SRC_SET_PRL_SS\r\n");

                    /* Clear DR SWAP of u32DPMStatus to retrigger DR_SWAP init flow after CC
                       attach again to fix issue that Iphone15 reboot and typec DP no signal */
                    DPM_CLR_DR_SWAP_INIT_STS(u8PortNum);

                    /* Enabling PRL Rx */
                    PRL_EnableRx (u8PortNum, HV_TRUE);

                    /* Enable Power Fault Threshold for TYPEC_VBUS_5V */
                    DPM_EnablePowerFaultDetection (u8PortNum);

                    /* Enable AME Monitoring */
#if(HV_TRUE == INCLUDE_PD_ALT_MODE)
                    DPM_EnableAMEMonitoring (u8PortNum);
#endif

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_RUN_SM_SS;

                    TypeC_CCDetHandleFunc(u8PortNum);
                    TypeC_CCUpdateMatchISR(u8PortNum);

                    DEBUG_PRINT_PORT_STR (gasTypeCcontrol[u8PortNum].u8CC1MatchISR<<16 | gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch,"u8CC1MatchISR u8CCSrcSnkMatch\r\n");
                    DEBUG_PRINT_PORT_STR (gasPolicyEngine[u8PortNum].ePEState<<16 | gasPolicyEngine[u8PortNum].ePESubState,"ePEState ePESubState\r\n");

                    /*Sink Attached in CC1 pin*/
                    if (gasTypeCcontrol[u8PortNum].u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch)
                    {
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~(TYPEC_CC_ATTACHED_ORIENTATION_MASK);
                        (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_CC1_ATTACH);
                    }
                    /*Sink attached in CC2*/
                    else
                    {
                        gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_CC_ATTACHED_ORIENTATION_MASK;
                        (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_CC2_ATTACH);
                    }

                    break;
                }

                case TYPEC_ATTACHED_SRC_RUN_SM_SS:
                case TYPEC_ATTACHED_SRC_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                case TYPEC_ATTACHED_SRC_SWAP_TRANS_TO_SNK_SS:
                {
                    /* This sub-state would be entered only during
                       Power role swap from Source to Sink */
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SRC_SWAP_TRANS_TO_SNK_SS\r\n");

                    /* Power down the CC comparator */
                    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                    /* Disable Rp terminations from both the CC pins and enable
                       Rd only in the connected CC pin.
                       Type C Spec Reference:
                       Note: If the port has entered this state from the Attached.SRC state as
                       the result of a USB PD PR_Swap/FR_Swap, the port shall terminate the
                       connected CC pin to ground through Rd and monitor its state */
                    if (TYPEC_ORIENTATION_CC1 == TYPEC_GET_CC_ORIENTATION_STS(u8PortNum))
                    {
                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1);
                    }
                    else /* Attached Orientation - CC2 */
                    {
                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC2);
                    }

                    /* Move the Type C SM to Attached SNK state since the
                       port is ready to act as Sink */
                    gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHED_SNK;
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_SWAP_ASSERT_RD_SS;

                    break;
                }
#endif

                default:
                    break;

            }
            break;
        }

        case TYPEC_UNATTACHED_WAIT_SRC:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                /*This SubState is used to start a tPDDeounce Software timer for sink detach event*/
                case TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS\r\n");

                    /*Kill all the timers for a port */
                    PDTimer_KillPortTimers (u8PortNum);

                    /*Disable VBUS by driving to vSafe0V*/
                    DPM_DriveVBUS (u8PortNum, DPM_VBUS_OFF);

                    /*Start the VBUS OFF timer for monitoring the time taken for
                     power module to reach vSafe0V*/
                    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start (
                                (TYPEC_VBUS_OFF_TIMER_MS),
                                DPM_VBUSOnOffOrVCONNOff_TimerCB, u8PortNum,
                                (UINT8)SET_TO_ZERO);

                    DEBUG_PRINT_PORT_STR (gasTypeCcontrol[u8PortNum].u8PortSts, "u8PortSts\r\n");
                    DEBUG_PRINT_PORT_STR (u8IntStsISR, "u8IntStsISR\r\n");
                    /*Enabling the VCONN Discharge if we are supplying VCONN or VCONN Req was ON*/
                    if (((u8IntStsISR & TYPEC_VCONN_SOURCE_MASK) != TYPEC_VCONN_DISABLED) \
                            || (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN_ON_REQ_MASK))
                    {
                        /*Disable VCONN by switching off the VCONN FETS*/
                        TypeC_EnabDisVCONN (u8PortNum, TYPEC_VCONN_DISABLE);

                        /*Clearing the VCONN ON Request mask if VCONN has turned OFF*/
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_VCONN_ON_REQ_MASK;

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_WAIT_FOR_VCONN_OFF_SS;
                    }
                    else
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_WAIT_FOR_VBUS_OFF_SS;
                    }

                    break;
                }

                /*Source waits in this SubState until the tPDDeounce Software timer expires or the VCONN
                Discharge is completed*/
                case TYPEC_UNATTACHED_WAIT_SRC_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                case TYPEC_UNATTACHED_WAIT_SRC_WAIT_FOR_VCONN_OFF_SS:
                {
                    if (!(u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_WAIT_FOR_VBUS_OFF_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                /*Wait in this sub-state until the VBUS goes to 0V before moving into Unattached state*/
                case TYPEC_UNATTACHED_WAIT_SRC_WAIT_FOR_VBUS_OFF_SS:
                {
                    // if (TYPEC_VBUS_0V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /* Turn off VBUS Discharge */
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        /*Kill the VBUS OFF timer since vSafe0V is reached*/
                        TypeC_KillTypeCTimer (u8PortNum);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SRC;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_UNORIENTED_DEBUG_ACCESSORY_SRC:
            break;

#endif
            /*INCLUDE_PD_SOURCE*/

            /*-----------------------------------------TypeC Sink States-------------------------------*/
#if (HV_TRUE == INCLUDE_PD_SINK)

        case TYPEC_UNATTACHED_SNK:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                case TYPEC_UNATTACHED_SNK_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC_UNATTACHED_SNK_ENTRY_SS\r\n");

#if (HV_TRUE == INCLUDE_PD_DRP)
                    /*Setting the Rd Value */
                    TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1_CC2);
#endif

                    gasDPM[u8PortNum].u16SinkOperatingCurrInmA = DPM_0mA;

                    // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
                    // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);

                    PRL_EnableRx (u8PortNum, HV_FALSE);

#if(HV_TRUE == INCLUDE_PD_DRP && HV_TRUE == INCLUDE_PD_DRP_TOGGLING)
                    if ((PD_ROLE_DRP != gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState) && \
                            (PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum)))
                    {
#if (HV_TRUE == INCLUDE_PD_FR_SWAP)
                        /*Disable DC_DC_EN which was turned on when enabling FRS detection */
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_FALSE);

                        if (DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))
                        {
                            Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_CC_HW_CTL_LOW, (UINT8)TYPEC_CC_DET_HBW_EN);

                            Hv_Typec_RegWriteByte (u8PortNum, UPD_CC_SAMP_CLK, \
                                              (UINT8) (UPD_CC_SAMP_GEN_10_KS | UPD_CC_CLK_20_KHZ));
                        }
#endif

                        /*Setting CC Comparator OFF*/
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                        gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_DRP;

                        /*Set power and data role status*/
                        DPM_UpdatePowerRole (u8PortNum, PD_ROLE_DRP);
                        DPM_UpdateDataRole (u8PortNum, PD_ROLE_TOGGLING);

                        Typec_SetFSMState(u8PortNum, TYPEC_FSM_STATE_UNATTACHED_SINK);

                        /*Enable DRP offload.*/
                        TypeC_DRPEnDisToggle(u8PortNum, HV_TRUE);
                    }
#endif
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_WAIT_FOR_VSAFE0V_SS;

                    break;
                }

                case TYPEC_UNATTACHED_SNK_WAIT_FOR_VSAFE0V_SS:
                {
                    // if (TYPEC_VBUS_0V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC_UNATTACHED_SNK_WAIT_FOR_VSAFE0V_SS" \
                                             " - VBUS_0V Present\r\n");

                        /* Disabling the VBUS discharge functionality since VBUS has reached vSafe0V */
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        /* Configure VBUS threshold to detect 5V*/
                        TypeC_ConfigureVBUSThr (u8PortNum, TYPEC_VBUS_5V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA, TYPEC_CONFIG_NON_PWR_FAULT_THR);

                        if (PD_ROLE_SINK == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum))
                        {
                            /*Setting CC Comparator OFF*/
                            TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                            /*Setting the CC Debounce register to detect both the sink and powered cable on CC1 and CC2*/
                            TypeC_SetCCSampleEnable (u8PortNum, TYPEC_ENABLE_CC1_CC2);

                            /*Setting CC Comparator ON*/
                            TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);
                        }

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_INIT_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                case TYPEC_UNATTACHED_SNK_INIT_SS:
                {
                    /*DPM power fault handler resets SM by polling this state TYPEC_UNATTACHED_SNK_INIT_SS
                    in the handler for Sink unattach.
                    Any module can reset its SM by polling this state*/
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_IDLE_SS;

                    /* Notify external DPM of Port enabled event through a user defined call back*/
                    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_PORT_ENABLED);

                    /*Notify external DPM of Type Detach event through a user defined call back*/
                    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_DETACH_EVENT);

                    break;
                }

                /*Sink Waits in this Sub-state for Source attachment*/
                case TYPEC_UNATTACHED_SNK_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_ATTACHWAIT_SNK:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                /*This SubState is used to start a tCCDebounce Software timer for Source attachment*/
                case TYPEC_ATTACHWAIT_SNK_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHWAIT_SNK_ENTRY_SS\r\n");

                    /* Configure VBUS threshold to detect 5V*/
                    TypeC_ConfigureVBUSThr (u8PortNum, TYPEC_VBUS_5V,  gasDPM[u8PortNum].u16SinkOperatingCurrInmA, TYPEC_CONFIG_NON_PWR_FAULT_THR);

                    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                            (TYPEC_TCCDEBOUNCE_TIMEOUT_MS), \
                            TypeC_SubStateChange_TimerCB, u8PortNum, \
                            TYPEC_ATTACHWAIT_SNK_CC_DEB_TIMEOUT_SS);

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_IDLE_SS;

                    break;
                }


                /*Sink Waits in this sub-state until either the tCCDebounce or tPDDebounce timer
                expires */
                case TYPEC_ATTACHWAIT_SNK_IDLE_SS:
                {
                    //DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC_ATTACHWAIT_SNK_IDLE_SS\r\n");
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                /*This SubState is used to start a tPDDebounce Software timer for Source detachment*/
                case TYPEC_ATTACHWAIT_SNK_START_PD_DEB_SS:
                {
#if(HV_TRUE == INCLUDE_PD_DRP && HV_TRUE == INCLUDE_PD_DRP_TOGGLING)
                    if (PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum))
                    {
                        /*Intentionally assigning u8DRPLastAttachedState as source to achieve
                         triggering of DRP offload enable in TYPEC_UNATTACHED_SRC_ENTRY_SS state
                         and thereby discovering a valid attach*/
                        gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SOURCE;

                        /*If source is detached during TYPEC_ATTACHWAIT_SNK state, according to
                        DRP state machine, the next state should be TYPEC_UNATTACHED_SRC*/
                        gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                                (TYPEC_TPDEBOUNCE_TIMEOUT_MS), \
                                TypeC_StateChange_TimerCB, u8PortNum, \
                                TYPEC_UNATTACHED_SRC);
                    }
                    else
#endif
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                                (TYPEC_TPDEBOUNCE_TIMEOUT_MS), \
                                TypeC_StateChange_TimerCB, u8PortNum, \
                                TYPEC_UNATTACHED_SNK);
                    }
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_IDLE_SS;

                    break;
                }


                /*Sink enters this sub-state after the tCCDebounce timer is expired */
                case TYPEC_ATTACHWAIT_SNK_CC_DEB_TIMEOUT_SS:
                {
                    /*Check for VBUS Presence before moving to Attached SNK state */
                    // if (TYPEC_VBUS_5V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_5V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHWAIT_SNK_CC_DEB_TIMEOUT_SS - VBUS_5V_PRESENT\r\n");
                        /*Set BLK_PD_MSG. Done in cronus*/
                        //Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_CC_HW_CTL_HIGH, TYPEC_BLK_PD_MSG);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_ENTRY_SS;
                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHED_SNK;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_ATTACHED_SNK:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                /* This sub-state would be entered from
                   Attached Source state during Source to Sink PR_Swap/FR_Swap */
                case TYPEC_ATTACHED_SNK_SWAP_ASSERT_RD_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_SWAP_ASSERT_RD_SS\r\n");

                    /* CC Comparator would have been turned off in
                       TYPEC_ATTACHED_SRC_SWAP_TRANS_TO_SNK_SS sub-state. No need
                       to do it here once again */

                    /* Configure the device role as UFP for the UPD350 to act as Sink */
                    //TypeC_SetCCDeviceRole (u8PortNum, PD_ROLE_UFP);

                    /*Set the u8CCDebMatch variable accordingly */
                    TypeC_SetCCDebounceVariable (u8PortNum, TYPEC_UFP);

                    UINT8 u8CCEnablePin, u8CCCompCtrl;
                    /* It is always recommended to enable thresholds on the other pin when we (as UPD350)
                       supply VCONN, to monitor changes in VCONN voltage, because VCONN is visible only to
                       the VCONN supplier and the cable on the supply end and is not visible to the port partner. */
                    if (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK)
                    {
                        u8CCEnablePin = TYPEC_ENABLE_CC1_CC2;
                        u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC1_CC2;
                    }
                    else /* Not VCONN Source */
                    {
                        /* We are not VCONN Source, enable CC Debounce thresholds only for
                           the connected CC pin. */
                        if (TYPEC_ORIENTATION_CC1 == TYPEC_GET_CC_ORIENTATION_STS(u8PortNum))
                        {
                            u8CCEnablePin = TYPEC_ENABLE_CC1;
                            u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC1;
                        }
                        else
                        {
                            u8CCEnablePin = TYPEC_ENABLE_CC2;
                            u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC2;
                        }
                    }
                    /*Reset the CC Debounce clear enable,CC Match Enable,CC Sample Enable register*/
                    TypeC_SetCCSampleEnable (u8PortNum, u8CCEnablePin);

                    /* Turn on the CC Comparator */
                    TypeC_ConfigCCComp (u8PortNum, u8CCCompCtrl);

                    /* Configure VBUS threshold to detect 5V*/
                    TypeC_ConfigureVBUSThr (u8PortNum, TYPEC_VBUS_5V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA, TYPEC_CONFIG_NON_PWR_FAULT_THR);

                    if (HV_TRUE == DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))
                    {
                        /*need update the cc status, because the cc status has been stable*/
                        TypeC_CCDetHandleFunc(u8PortNum);

                        /* During FR_Swap, 5V will have already been present in VBUS.
                           Again checking for 5V presence is not necessary. Therefore,
                           wait for CC attach from initial sink */
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_SWAP_ATTACH_DETECT_SS;
                    }
                    else
                    {
                        /* During PR_Swap, wait for vSafe5V from Original Sink */
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_SWAP_VBUS_PRES_DETECT_SS;
                    }
                    break;
                }

                case TYPEC_ATTACHED_SNK_SWAP_VBUS_PRES_DETECT_SS:
                {
                    /*Check for VBUS Presence before moving to Attached SNK state */
                    // if (TYPEC_VBUS_5V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_5V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /* If VSink_Disconnect interrupt had occurred, VBUS_DIS would have been
                           turned on TypeC_HandleISR(). Since this interrupt will not be handled
                           during a Role Swap, turning off the VBUS Discharge here*/
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_SWAP_VBUS_PRES_DETECT_SS\r\n");

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_ENTRY_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                case TYPEC_ATTACHED_SNK_SWAP_ATTACH_DETECT_SS:
                {
                    /* Wait for CC attach*/
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    break;
                }
#endif
                /*Sink enables the CC Communication channel and notifies the external DPM
                about the Type C Attached event this sub-state */
                case TYPEC_ATTACHED_SNK_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_ENTRY_SS\r\n");

                    /* Assign Operating current based on the Rp value*/
                    gasDPM[u8PortNum].u16SinkOperatingCurrInmA = TypeC_ObtainCurrentValueFrmRp(u8PortNum);

#if(HV_TRUE == INCLUDE_PD_DRP)
                    if (PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum))
                    {
                        gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SINK;
                    }
#endif

                    // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
                    // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_5V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);

                    /* Enabling PRL Rx*/
                    PRL_EnableRx (u8PortNum, HV_TRUE);

                    /* Enable Power Threshold for TYPEC_VBUS_5V */
                    TypeC_ConfigureVBUSThr (u8PortNum, TYPEC_VBUS_5V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA, TYPEC_CONFIG_PWR_FAULT_THR);

                    /* Enable AME Monitoring  */
#if(HV_TRUE == INCLUDE_PD_ALT_MODE)
                    DPM_EnableAMEMonitoring (u8PortNum);
#endif

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_RUN_SM_SS;

                    TypeC_CCUpdateMatchISR(u8PortNum);
                    /* Update connected CC orientation status */
                    /*Source Attached in CC1 pin*/

                    if (u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch)
                    {
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~(TYPEC_CC_ATTACHED_ORIENTATION_MASK);
                        //Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_CC_CTL1_HIGH, TYPEC_CC_COM_SEL);        //CC Communication Sel no use.

                        (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_CC1_ATTACH);
                    }
                    /*Source Attached in CC2 pin*/
                    else
                    {
                        gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_CC_ATTACHED_ORIENTATION_MASK;
                        //Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_CC_CTL1_HIGH, TYPEC_CC_COM_SEL);

                        (void)DPM_NotifyClient (u8PortNum, eHV_PSF_TYPEC_CC2_ATTACH);
                    }

                    break;
                }

                case TYPEC_ATTACHED_SNK_RUN_SM_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                /*Sink enters this sub-state to start a tPDDeounce timer for source detach event*/
                case TYPEC_ATTACHED_SNK_START_PD_DEB_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_START_PD_DEB_SS\r\n");

                    /*Kill all the timers for a port before starting a Type C Debounce timer*/
                    PDTimer_KillPortTimers (u8PortNum);

                    /* Start a Debounce timer of tPDDebounce for detach event*/
                    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                            (TYPEC_TPDEBOUNCE_TIMEOUT_MS), \
                            TypeC_SubStateChange_TimerCB, u8PortNum, \
                            TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS);

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_IDLE_SS;

                    break;
                }

                /*Sink enters this sub-state after the tPDDeounce timer is expired or VBUS drops below
                vSinkDisconnect*/
                case TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS\r\n");

                    // if ((u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK) != TYPEC_VBUS_0V_PRES)
                    if (TYPEC_VBUS_0V != DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /*Enabling the VBUS discharge functionality for VBUS to go to vSafe0V*/
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_TRUE);
                    }

                    gasDPM[u8PortNum].u16SinkOperatingCurrInmA = DPM_0mA;
                    /*Disable the Sink circuitry to stop sinking the power from source*/
                    // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
                    // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);

                    /*Enabling the VCONN Discharge if we are supplying VCONN or VCONN ON Req is set*/
                    if (((u8IntStsISR & TYPEC_VCONN_SOURCE_MASK) != TYPEC_VCONN_DISABLED) || \
                            (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN_ON_REQ_MASK))
                    {
                        /*Disable VCONN by switching off the VCONN FETS*/
                        TypeC_EnabDisVCONN (u8PortNum, TYPEC_VCONN_DISABLE);

                        /*Clearing the VCONN ON Request mask if VCONN has turned ON*/
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_VCONN_ON_REQ_MASK;

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_WAIT_FOR_VCONN_OFF_SS;
                    }
                    else
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SNK;
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;
                    }
                    break;
                }

                case TYPEC_ATTACHED_SNK_WAIT_FOR_VCONN_OFF_SS:
                {
                    if (!(u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SNK;
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                /*Sink waits in this sub-state until the tPDDeounce timer expires or until the VCONN
                Discharge is completed*/
                case TYPEC_ATTACHED_SNK_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                case TYPEC_ATTACHED_SNK_SWAP_TRANS_TO_SRC_SS:
                {
                    /* This sub-state would be entered only during
                       Power role swap from Sink to Source */
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_SWAP_TRANS_TO_SRC_SS\r\n");
                    /* Power down the CC comparator */
                    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                    /* Get Rp current source value from user configuration */
                    UINT8 u8RpValue = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);

                    /* Disable Rd terminations from both the CC pins and enable
                       Rp only in the connected CC pin.
                       Type C Spec Reference:
                       Note: If the port has entered this state from the Attached.SNK state as
                       the result of a USB PD PR_Swap/FR_Swap, the port shall source current on the
                       connected CC pin and monitor its state */
                    if (TYPEC_ORIENTATION_CC1 == TYPEC_GET_CC_ORIENTATION_STS(u8PortNum))
                    {
                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, u8RpValue, TYPEC_ENABLE_CC1);
                    }
                    else /* Attached Orientation - CC2 */
                    {
                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, u8RpValue, TYPEC_ENABLE_CC2);
                    }

                    /*Setting user given Rp Value as Current Rp Value in CurrentRpVal bit of u8PortSts variable*/
                    gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;
                    gasTypeCcontrol[u8PortNum].u8PortSts |= (u8RpValue << TYPEC_CURR_RPVAL_POS);

                    /* Move the Type C SM to Attached Src state since the
                       port is ready to act as Source */
                    gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHED_SRC;
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SRC_SWAP_ASSERT_RP_SS;

                    /* in case for source do not discharge */
                    PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_TRUE);
                    break;
                }
#endif
                default:
                    break;
            }
            break;
        }
        case TYPEC_DEBUG_ACCESSORY_SNK:
            break;

#endif
        /*INCLUDE_PD_SINK*/

        case TYPEC_ERROR_RECOVERY:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                /*In this SubState, VBUS and VCONN are disabled.Pull down and Pull up resistors
                are set to open disconnect*/
                case TYPEC_ERROR_RECOVERY_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ERROR_RECOVERY_ENTRY_SS\r\n");

                    /* Disable the receiver*/
                    PRL_EnableRx (u8PortNum, HV_FALSE);

                    /* Disable EN_FRS pin when FRS is enabled for the port */
#if (HV_TRUE == INCLUDE_PD_FR_SWAP)
                    PWRCTRL_DisableEnFRS (u8PortNum);
#endif

                    /*Setting CC Comparator OFF*/
                    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
                    {
#if(HV_TRUE == INCLUDE_PD_SOURCE)
                        /*Disable VBUS by driving to vSafe0V*/
                        DPM_DriveVBUS (u8PortNum, DPM_VBUS_OFF);

                        /*Disable DC_DC EN on VBUS fault to reset the DC-DC controller*/
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_FALSE);

                        /*Setting the CC1 and CC2 line as Open Disconnect*/
#if (HV_TYPEC_CONFIG_TYPEC_ERROR_RECOVERY_NEW == 1)
                        Hv_Drv_Typec_SwCtrlRpRd(u8PortNum, 0);
#else
                        TypeC_SetCCPowerRole (u8PortNum, PD_ROLE_SOURCE, TYPEC_ROLE_SOURCE_OPEN_DIS, TYPEC_ENABLE_CC1_CC2);
#endif
#endif
                    }
                    else
                    {
#if (HV_TRUE == INCLUDE_PD_SINK)
                        /*Kill active timers if any*/
                        PDTimer_KillPortTimers (u8PortNum);

                        gasDPM[u8PortNum].u16SinkOperatingCurrInmA = DPM_0mA;

                        // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
                        /*Disable the Sink circuitry to stop sinking the power from source*/
                        // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);

                        /*Setting the CC1 and CC2 line as Open Disconnect*/
#if (HV_TYPEC_CONFIG_TYPEC_ERROR_RECOVERY_NEW == 1)
                        Hv_Drv_Typec_SwCtrlRpRd(u8PortNum, 0);
#else
                        TypeC_SetCCPowerRole (u8PortNum, PD_ROLE_SINK, TYPEC_ROLE_SINK_OPEN_DIS, TYPEC_ENABLE_CC1_CC2);
#endif
#endif
                    }

#if (INCLUDE_PD_VCONN_SWAP | INCLUDE_PD_SOURCE)
                    /*Disable VCONN if the port sources the VCONN already or failed while trying to
                    source VCONN*/
                    if (((u8IntStsISR & TYPEC_VCONN_SOURCE_MASK) \
                            != TYPEC_VCONN_DISABLED) || (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN_ON_REQ_MASK))
                    {
                        /*Clearing the VCONN ON Request mask if VCONN has turned ON*/
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_VCONN_ON_REQ_MASK;

                        /*Disable VCONN by switching off the VCONN FETS*/
                        TypeC_EnabDisVCONN (u8PortNum, TYPEC_VCONN_DISABLE);
                    }

                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ERROR_RECOVERY_WAIT_FOR_VCONN_OFF_SS;

#else
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ERROR_RECOVERY_WAIT_FOR_VBUS_OFF_SS;
#endif
                    break;
                }

#if (INCLUDE_PD_VCONN_SWAP | INCLUDE_PD_SOURCE)
                case TYPEC_ERROR_RECOVERY_WAIT_FOR_VCONN_OFF_SS:
                {
                    if (!(u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ERROR_RECOVERY_WAIT_FOR_VBUS_OFF_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }
#endif

                case TYPEC_ERROR_RECOVERY_WAIT_FOR_VBUS_OFF_SS:
                {
                    // if (TYPEC_VBUS_0V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /* Turn off VBUS Discharge */
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        /*Setting VBUS Comparator OFF once the VBUS line goes off to 0V*/
                        TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

                        gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                                (TYPEC_ERRORRECOVERY_TIMEOUT_MS), \
                                TypeC_SubStateChange_TimerCB, u8PortNum, \
                                TYPEC_ERROR_RECOVERY_TIMEOUT_SS);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ERROR_RECOVERY_IDLE_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                /*Device waits in this sub-state until the tErrorRecovery software timer expires*/
                case TYPEC_ERROR_RECOVERY_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                /*Device enters this sub-state after the tErrorRecovery software timer is expired*/
                case TYPEC_ERROR_RECOVERY_TIMEOUT_SS:
                {
#if (HV_TYPEC_CONFIG_TYPEC_ERROR_RECOVERY_NEW == 1)
                    Hv_Drv_Typec_SwCtrlRpRd(u8PortNum, 1);
                    TypeC_InitDRPPort(u8PortNum);
                    /* 置为SOURCE ROLE的目的是为了source没attach后进入toggle */
                    gasTypeCcontrol[u8PortNum].u8DRPLastAttachedState = PD_ROLE_SOURCE;
#else
                    /*Resetting the Port Power Role*/
                    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
                    {
#if(HV_TRUE == INCLUDE_PD_SOURCE)
                        UINT8 u8Data;

                        /*Setting Rp Current Source as user given and Rd as Open disconnect in both
                        CC1 and CC2*/
                        u8Data = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);

                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, u8Data, TYPEC_ENABLE_CC1_CC2);

                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SRC;
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;

                        /*Enable DC_DC EN on VBUS fault to reset the DC-DC controller*/
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_TRUE);
#endif
                    }
                    else
                    {
#if(HV_TRUE == INCLUDE_PD_SINK)
                        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1_CC2);

                        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SNK;
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;
#endif
                    }
#endif
                    /*Setting CC Comparator ON*/
                    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);
                    /*Setting VBUS Comparator ON*/
                    TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_ON);
                    break;
                }

                default:
                    break;
            }
            break;
        }

        case TYPEC_DISABLED:
        {
            switch (gasTypeCcontrol[u8PortNum].u8TypeCSubState)
            {
                /* As per Type C Spec, Disabled State Requirements are,
                The port shall not drive VBUS or VCONN, and shall
                present a high-impedance to ground (above zOPEN) on
                its CC1 and CC2 pins. */
                case TYPEC_DISABLED_ENTRY_SS:
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_DISABLED_ENTRY_SS\r\n");

                    /* Disable the receiver*/
                    PRL_EnableRx (u8PortNum, HV_FALSE);

                    /*Setting CC Comparator OFF*/
                    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                    /*Kill active timers if any*/
                    PDTimer_KillPortTimers (u8PortNum);

                    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
                    {
#if (HV_TRUE == INCLUDE_PD_SOURCE)
                        /*Disable VBUS by driving to vSafe0V*/
                        DPM_DriveVBUS (u8PortNum, DPM_VBUS_OFF);

                        /*Disable DC_DC EN on VBUS fault to reset the DC-DC controller*/
                        PWRCTRL_ConfigDCDCEn (u8PortNum, HV_FALSE);

                        /*Setting the CC1 and CC2 line as Open Disconnect*/
                        TypeC_SetCCPowerRole (u8PortNum, PD_ROLE_SOURCE, TYPEC_ROLE_SOURCE_OPEN_DIS, TYPEC_ENABLE_CC1_CC2);

                        /* Clear TypeC Current Rp Val bits in u8PortSts so that in unattached
                        SRC state, the Rp value from user configuration would be set. */
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;
#endif
                    }
                    else if (PD_ROLE_SINK == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
                    {
#if (HV_TRUE == INCLUDE_PD_SINK)
                        gasDPM[u8PortNum].u16SinkOperatingCurrInmA = DPM_0mA;

                        TypeC_ConfigureVBUSThr (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA, TYPEC_CONFIG_NON_PWR_FAULT_THR);

                        // PWRCTRL_ConfigSinkHW 调用被移除，因为它没有实际作用
                        /*Disable the Sink circuitry to stop sinking the power from source*/
                        // PWRCTRL_ConfigSinkHW (u8PortNum, TYPEC_VBUS_0V, gasDPM[u8PortNum].u16SinkOperatingCurrInmA);

                        /*Setting the CC1 and CC2 line as Open Disconnect*/
                        TypeC_SetCCPowerRole (u8PortNum, PD_ROLE_SINK, TYPEC_ROLE_SINK_OPEN_DIS, TYPEC_ENABLE_CC1_CC2);
#endif
                    }
                    else
                    {
                        /*Do nothing*/
                    }

                    /*Disable VCONN if the port sources the VCONN already or failed while trying to
                    source VCONN*/
                    if (((u8IntStsISR & TYPEC_VCONN_SOURCE_MASK) \
                            != TYPEC_VCONN_DISABLED) || (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN_ON_REQ_MASK))
                    {
                        /*Clearing the VCONN ON Request mask if VCONN has turned ON*/
                        gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_VCONN_ON_REQ_MASK;

                        /*Disable VCONN by switching off the VCONN FETS*/
                        TypeC_EnabDisVCONN (u8PortNum, TYPEC_VCONN_DISABLE);

                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_WAIT_FOR_VCONN_OFF_SS;
                    }
                    else
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_WAIT_FOR_VBUS_OFF_SS;
                    }

                    break;
                }

                case TYPEC_DISABLED_WAIT_FOR_VCONN_OFF_SS:
                {
                    if (!(u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
                    {
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_WAIT_FOR_VBUS_OFF_SS;
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                case TYPEC_DISABLED_WAIT_FOR_VBUS_OFF_SS:
                {
                    // if (TYPEC_VBUS_0V_PRES == (u8IntStsISR & TYPEC_VBUS_PRESENCE_MASK))
                    if (TYPEC_VBUS_0V == DPM_GetVBUSVoltage(u8PortNum))
                    {
                        /*Setting VBUS Comparator OFF once the VBUS line goes off to 0V*/
                        TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

                        /*Disable the VBUS discharge functionality since VBUS has reached vSafe0V*/
                        PWRCTRL_ConfigVBUSDischarge (u8PortNum, HV_FALSE);

                        /*Setting CC Comparator OFF*/
                        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

                        if (PD_ROLE_SINK == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
                        {
                            /*Wait for TYPEC_ERRORRECOVERY_TIMEOUT_MS time as specified in Spec*/
                            gasTypeCcontrol[u8PortNum].u8TypeCTimerID = PDTimer_Start ( \
                                    (TYPEC_ERRORRECOVERY_TIMEOUT_MS), \
                                    TypeC_SubStateChange_TimerCB, u8PortNum, \
                                    TYPEC_DISABLED_TIMEOUT_SS);

                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_IDLE_SS;
                        }
                        else
                        {
                            gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_TIMEOUT_SS;
                        }
                    }
                    else
                    {
                        /* Hook to notify Type C state machine entry into idle sub-state */
                        HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);
                    }
                    break;
                }

                /*Device waits in this sub-state until the tErrorRecovery software timer expires*/
                case TYPEC_DISABLED_IDLE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }

                case TYPEC_DISABLED_TIMEOUT_SS:
                {
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_DISABLED_DONE_SS;

                    /* Notify external DPM of Port disabled event through a user defined call back*/
                    (void)DPM_NotifyClient (u8PortNum, eHV_PSF_PORT_DISABLED);

                    break;
                }

                case TYPEC_DISABLED_DONE_SS:
                {
                    /* Hook to notify Type C state machine entry into idle sub-state */
                    HV_PSF_HOOK_NOTIFY_IDLE (u8PortNum, eIDLE_TYPEC_NOTIFY);

                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
        }

        case TYPEC_AUDIO_ACCESSORY:
            break;

        default:
            break;
    }

}

static UINT8 TypeC_GetCCMatch(UINT8 u8PortNum, UINT8 u8CCAdcIn, UINT8 u8CCDebMatch)
{
    UINT8 u8CCMatch = 0;

    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        u8CCMatch = 0xFF;
        if (u8CCAdcIn < TYPEC_CC_THR0_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES0_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR1_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES1_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR2_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES2_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR3_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES3_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR4_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES4_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR5_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES5_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR6_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES6_MATCH;
        }
        if (u8CCAdcIn < TYPEC_CC_THR7_VAL)
        {
            u8CCMatch &= ~TYPEC_CC_THRES7_MATCH;
        }

        u8CCMatch = ~u8CCMatch;

    }
    else
    {
        u8CCMatch = 0;
        if (u8CCAdcIn > TYPEC_CC_THR0_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES0_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR1_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES1_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR2_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES2_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR3_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES3_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR4_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES4_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR5_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES5_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR6_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES6_MATCH;
        }
        if (u8CCAdcIn > TYPEC_CC_THR7_VAL)
        {
            u8CCMatch |= TYPEC_CC_THRES7_MATCH;
        }
    }

    u8CCMatch &= u8CCDebMatch;

    return u8CCMatch;
}

/*******************************************************************************************/
/*********************************TypeC Interrupt Handler**************************************/
/*******************************************************************************************/


static VOID TypeC_GetCCStatus(UINT8 u8PortNum, TypeC_CCStatus *psCCStatus)
{
    UINT32 uiReadData;
    UINT8 u8CCDebMatch = gasTypeCcontrol[u8PortNum].u8CCDebMatch;

    // Get CC1 ADC value and match status
    uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC1_ADC_IN);
    psCCStatus->cc1AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);
    psCCStatus->cc1Match = TypeC_GetCCMatch(u8PortNum, psCCStatus->cc1AdcIn, u8CCDebMatch);

    // Get CC2 ADC value and match status  
    uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC2_ADC_IN);
    psCCStatus->cc2AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);
    psCCStatus->cc2Match = TypeC_GetCCMatch(u8PortNum, psCCStatus->cc2AdcIn, u8CCDebMatch);
}


// 辅助函数用于状态判断
static BOOL TypeC_IsCCStateFSMMatch(UINT8 u8FSMState, const TypeC_CCStatus *psCCStatus)
{
    switch (u8FSMState) {
        case TYPEC_FSM_STATE_ATTACHED_SOURCE:
            // CC 必须至少有一个有效连接
            return (psCCStatus->cc1Match != 0) || (psCCStatus->cc2Match != 0);
            
        case TYPEC_FSM_STATE_UNATTACHED_SINK:
            // 两个 CC 都应该无连接
            return (psCCStatus->cc1Match == 0) && (psCCStatus->cc2Match == 0);
            
        // ...其他状态判断
        
        default:
            return HV_TRUE;
    }
}

static BOOL TypeC_IsInVDMState(UINT8 u8PortNum)
{
    return (((ePE_VDM_INITIATE_VDM == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_REQUEST == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_EVALUATE_VDM == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_ACKED == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_NAKED == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_RESPOND_VDM == gasPolicyEngine[u8PortNum].ePEState)) ? HV_TRUE : HV_FALSE);
}

static VOID TypeC_HandleCCDetIntr(UINT8 u8PortNum, const TypeC_CCStatus *psCCStatus) 
{
    // 1. 添加 VDM 状态判断，防止 VDM 过程中的 ADC 抖动导致错误处理
    if(TypeC_IsInVDMState(u8PortNum))
    {
        DEBUG_PRINT_PORT_STR((u8PortNum<<16) | gasPolicyEngine[u8PortNum].ePEState,
                            "Skip CC interrupt in VDM state\r\n");
    //     return;
    }

    // 2. 添加 CC 电平异常判断
#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_OFF)
    if ((psCCStatus->cc1AdcIn > TYPEC_CC_ABNORMAL_THR) || (psCCStatus->cc2AdcIn > TYPEC_CC_ABNORMAL_THR))
    {
        DEBUG_PRINT_PORT_STR(psCCStatus->cc1AdcIn<<16 | psCCStatus->cc2AdcIn, "Abnormal CC voltage detected\r\n");
        return;
    }
#endif

    // 3. 添加 FSM 状态与 CC 状态不匹配的检查
    // UINT8 u8FSMState = u8GetTypecFSMState(u8PortNum);

    // if (!TypeC_IsCCStateFSMMatch(u8FSMState, psCCStatus)) {
        // DEBUG_PRINT_PORT_STR(u8PortNum, "CC state not match FSM state\r\n");
        // 根据具体情况决定是否需要强制状态切换
        // if (TypeC_NeedForceFSMChange(u8FSMState, psCCStatus)) {
            // TypeC_HandleFSMMismatch(u8PortNum, u8FSMState, psCCStatus);
        // }
        // return;
    // }

    // 4. 更新 CC 状态
    gasTypeCcontrol[u8PortNum].u8CC1MatchISR = psCCStatus->cc1Match;
    gasTypeCcontrol[u8PortNum].u8CC2MatchISR = psCCStatus->cc2Match;
    DEBUG_PRINT_PORT_STR(psCCStatus->cc1AdcIn<<24 | psCCStatus->cc2AdcIn<<16 | psCCStatus->cc1Match<<8 | psCCStatus->cc2Match,
        "TypeC_HandleCCDetIntr cc1AdcIn cc2AdcIn cc1Match cc2Match\r\n");
        
    gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_CCINT_STATUS_MASK;
}

#if 0
void TypeC_CCDetIntHandleFunc(UINT8 u8PortNum, UINT32 u32CCPwrDet)
{
    UINT8 u8CC1AdcIn = 0;
    UINT8 u8CC2AdcIn = 0;
    UINT8 u8CC1Match = gasTypeCcontrol[u8PortNum].u8CC1MatchISR;
    UINT8 u8CC2Match = gasTypeCcontrol[u8PortNum].u8CC2MatchISR;
    UINT8 u8CCDebMatch = gasTypeCcontrol[u8PortNum].u8CCDebMatch;
    UINT32 uiReadData = 0;

#if TYPEC_CC_INT_ONLY_USE_ADC_IN
    UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK);

    u8RegVal &= UPD_PWR_DET_CC_ADCIN_CHG_MASK;

    if (u8RegVal & UPD_PWR_DET_CC1_ADCIN_CHG_MASKBIT)
    {
        uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC1_ADC_IN);
        u8CC1AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);
        u8CC1Match = TypeC_GetCCMatch(u8PortNum, u8CC1AdcIn, u8CCDebMatch);
        gasTypeCcontrol[u8PortNum].u8CC1MatchISR = u8CC1Match;
        gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_CCINT_STATUS_MASK;
    }

    if (u8RegVal & UPD_PWR_DET_CC2_ADCIN_CHG_MASKBIT)
    {
        uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC2_ADC_IN);
        u8CC2AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);
        u8CC2Match = TypeC_GetCCMatch(u8PortNum, u8CC2AdcIn, u8CCDebMatch);
        gasTypeCcontrol[u8PortNum].u8CC2MatchISR = u8CC2Match;
        gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_CCINT_STATUS_MASK;
    }

    if (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_CCINT_STATUS_MASK)
    {
        UINT8 u8Data = SET_TO_ZERO;
        /*Get the state being advertised from DRP_CTL_HIGH register*/
        Hv_Typec_RegisterReadISR (u8PortNum, UPD_REG_RO_FSM_STATE, &u8Data, BYTE_LEN_1);

        DEBUG_PRINT_PORT_STR (((UINT32)gasTypeCcontrol[u8PortNum].u8TypeCState<<16) | (u8CC1AdcIn<<8) | u8CC2AdcIn,"TypeC_CCDetIntHandleFunc u8CCAdcIn\r\n");
        DEBUG_PRINT_PORT_STR (((UINT32)u8PortNum<<24) | (u8Data<<16) | (u8CC1Match<<8) | u8CC2Match,"TypeC_CCDetIntHandleFunc u8CCMatch\r\n");

        if (gasTypeCcontrol[u8PortNum].u8TypeCState==TYPEC_ATTACHED_SRC/* || gasTypeCcontrol[u8PortNum].u8TypeCState==TYPEC_ATTACHED_SNK*/)
        {
            DEBUG_PRINT_PORT_STR (u8CCDebMatch,"TypeC_CCDetIntHandleFunc u8CCDebMatch\r\n");
        }

#if(HV_TRUE == INCLUDE_PD_DRP)
        /**
         * 在解决macbook pro M1笔记本关机后笔记本自动重启的bug中发现，当CC1和CC2 ADC全是3.3V的时候，
         * Typec HW FSM却是2，这个case是不应该出现的。下面的workaround用于解决该问题导致的软件流程错误。
         */
        if ((gasTypeCcontrol[u8PortNum].u8CC1MatchISR == 0) && (gasTypeCcontrol[u8PortNum].u8CC2MatchISR == 0)
            && (TYPEC_FSM_STATE_UNATTACHED_SINK == (u8Data & UPD_FSM_STATE_MASK)))
        {
            gasTypeCcontrol[u8PortNum].u8IntStsISR &= ~TYPEC_CCINT_STATUS_MASK;
            DEBUG_PRINT_PORT_STR (u8PortNum,"TypeC_CCDetIntHandleFunc fsm 2 BUT CC ADC is 3.3V\r\n");
            return;
        }

        if ((gasTypeCcontrol[u8PortNum].u8CC1MatchISR == 0) && (gasTypeCcontrol[u8PortNum].u8CC2MatchISR == 0)
            && (gasTypeCcontrol[u8PortNum].u8TypeCState==TYPEC_ATTACHED_SRC))
        {
            if (TYPEC_FSM_STATE_ATTACH_WAIT_SOURCE != (u8Data & UPD_FSM_STATE_MASK) &&
                TYPEC_FSM_STATE_ATTACHED_SOURCE != (u8Data & UPD_FSM_STATE_MASK))
            {
                /*Set the FSM to unattached source state*/

                UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT);
                u8RegVal &= ~UPD_FSM_CMD_DIRECT_MASK;
                u8RegVal |= TYPEC_FSM_STATE_UNATTACHED_SOURCE;
                Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, u8RegVal);        //init to force the FSM
                Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, UPD_FSM_CMD_DIRECT_EN);
                Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_FSM_CMD_DIRECT, UPD_FSM_CMD_DIRECT_EN);
                Typec_SetFSMState(u8PortNum, TYPEC_FSM_STATE_UNATTACHED_SOURCE);
                TypeC_DRPEnDisToggle(u8PortNum, HV_TRUE);

                DEBUG_PRINT_PORT_STR (u8PortNum,"TypeC_CCDetIntHandleFunc u8CC1MatchISR u8CC1MatchISR both 0 in src\r\n");
            }
            else
            {
                gasPolicyEngine[u8PortNum].ePEState = ePE_INVALIDSTATE;
                gasPolicyEngine[u8PortNum].ePESubState = ePE_INVALIDSUBSTATE;
                gasTypeCcontrol[u8PortNum].u8IntStsISR &= ~TYPEC_CCINT_STATUS_MASK;
                DEBUG_PRINT_PORT_STR (u8PortNum,"TypeC_CCDetIntHandleFunc u8CC1MatchISR u8CC1MatchISR both 0 in src but not in attach\r\n");
            }
        }
#endif

#if(INCLUDE_PD_ALT_MODE == HV_TRUE)
    gasCfgStatusData.sVDMPerPortData[u8PortNum].u8SVDMHpdHighFlag = HV_FALSE;
#endif
    }
#else
    /* workround for ADC jitter */
    UINT8 u8PEInVDMState = (((ePE_VDM_INITIATE_VDM == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_REQUEST == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_EVALUATE_VDM == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_ACKED == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_IDENTITY_NAKED == gasPolicyEngine[u8PortNum].ePEState) || \
      (ePE_VDM_RESPOND_VDM == gasPolicyEngine[u8PortNum].ePEState)) ? HV_TRUE : HV_FALSE);
    /* CC ADC IN */
    if(u32CCPwrDet & ((BIT_13)|(BIT_14)))
    {
        if(((gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus & DPM_PORT_ATTACHED_STATUS)
            && !(gasPolicyEngine[u8PortNum].u8PEPortSts & PE_EXPLICIT_CONTRACT)) ||
            (u8PEInVDMState))
        {
            /* do nothing */
        }
        else
        {
            UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK);

            u8RegVal &= UPD_PWR_DET_CC_ADCIN_CHG_MASK;

            if (u8RegVal & UPD_PWR_DET_CC1_ADCIN_CHG_MASKBIT)
            {
                uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC1_ADC_IN);
                u8CC1AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);

                u8CC1Match = TypeC_GetCCMatch(u8PortNum, u8CC1AdcIn, u8CCDebMatch);
            }

            if (u8RegVal & UPD_PWR_DET_CC2_ADCIN_CHG_MASKBIT)
            {
                uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC2_ADC_IN);
                u8CC2AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);

                u8CC2Match = TypeC_GetCCMatch(u8PortNum, u8CC2AdcIn, u8CCDebMatch);
            }

            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_CCINT_STATUS_MASK;

            gasTypeCcontrol[u8PortNum].u8CC1MatchISR = u8CC1Match;
            gasTypeCcontrol[u8PortNum].u8CC2MatchISR = u8CC2Match;

            HV_PSF_HOOK_TASK_PRIORITY_SET(TYPEC_NORMAL_TASK_PRIORITY);
            //HV_PSF_HOOK_SEND_EVENT_TO_QUEUE_FROM_ISR(TYPEC_EVENT_GO, 0);
        }
    }
    /* CC Voltage change */
    if(u32CCPwrDet & ((BIT_16)|(BIT_17)))
    {
        if(((gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus & DPM_PORT_ATTACHED_STATUS)
            && !(gasPolicyEngine[u8PortNum].u8PEPortSts & PE_EXPLICIT_CONTRACT)) ||
            (u8PEInVDMState))
        {
            UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_CCVOL_DET_IRQMASK);

            u8RegVal &= UPD_CCVOL_DET_CC_CHG_MASK;

            if (u8RegVal & UPD_CCVOL_DET_CC0_CHG_MASKBIT)
            {
                uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC1_ADC_IN);
                u8CC1AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);

                u8CC1Match = TypeC_GetCCMatch(u8PortNum, u8CC1AdcIn, u8CCDebMatch);
            }

            if (u8RegVal & UPD_CCVOL_DET_CC1_CHG_MASKBIT)
            {
                uiReadData = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC2_ADC_IN);
                u8CC2AdcIn = (UINT8)((uiReadData & 0xFFF) >> 4);

                u8CC2Match = TypeC_GetCCMatch(u8PortNum, u8CC2AdcIn, u8CCDebMatch);
            }

            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_CCINT_STATUS_MASK;

            gasTypeCcontrol[u8PortNum].u8CC1MatchISR = u8CC1Match;
            gasTypeCcontrol[u8PortNum].u8CC2MatchISR = u8CC2Match;

            HV_PSF_HOOK_TASK_PRIORITY_SET(TYPEC_NORMAL_TASK_PRIORITY);
            //HV_PSF_HOOK_SEND_EVENT_TO_QUEUE_FROM_ISR(TYPEC_EVENT_GO, 0);
#if(HV_TRUE == INCLUDE_PD_DRP)
            bDrpToggleFlag = HV_TRUE;
#endif
#if(INCLUDE_PD_ALT_MODE == HV_TRUE)
            gasCfgStatusData.sVDMPerPortData[u8PortNum].u8SVDMHpdHighFlag = HV_FALSE;
#endif
        }
        else
        {
            /* do nothing */
        }
    }
#endif

#if TYPEC_DEBUG_TRACE_EN
    {
        static UINT32 counts = 0;
        HV_W32(0x11011A00 + counts * 8, ((u32CCPwrDet & ((BIT_16)|(BIT_17))) >> 8) | ((u32CCPwrDet & ((BIT_13)|(BIT_14))) >> 13));
        HV_W32(0x11011A00 + counts * 8 + 4, (u8CC1AdcIn << 24) | (u8CC2AdcIn << 16) | (u8CC1Match << 8) | (u8CC2Match));
        if (++counts >= 25)
        {
            counts = 0;
        }
    }
#endif
}
#endif


// CC去抖定时器回调
static void TypeC_CCDebounce_TimerCB(UINT8 u8PortNum, UINT8 u8Data)
{
    DEBUG_PRINT_PORT_STR(u8PortNum, "TypeC_CCDebounce_TimerCB\r\n");

    TypeC_CCDebounce_T *psDebounce = &s_CCDebounce[u8PortNum];
    
    // 获取当前CC状态
    TypeC_CCStatus sCCStatus = {0};
    TypeC_GetCCStatus(u8PortNum, &sCCStatus);

    psDebounce->bDebouncing = HV_FALSE;
    psDebounce->u8TimerId = MAX_CONCURRENT_TIMERS;

    // 判断是否与去抖开始时的状态一致
    if ((psDebounce->u8LastCC1Match == sCCStatus.cc1Match) &&
        (psDebounce->u8LastCC2Match == sCCStatus.cc2Match)) {
        // 状态稳定,处理CC中断
        TypeC_HandleCCDetIntr(u8PortNum, &sCCStatus);
        // 重置计数
        psDebounce->u8DebounceCount = 0;
    } else {        
        psDebounce->u8DebounceCount++;
        
        if(psDebounce->u8DebounceCount >= MAX_DEBOUNCE_COUNT) {
            // 达到最大次数,使用最后一次的状态
            DEBUG_PRINT_PORT_STR(u8PortNum, "Max debounce count reached, use last stable state\r\n");
            TypeC_HandleCCDetIntr(u8PortNum, &sCCStatus);
            psDebounce->u8DebounceCount = 0;
        } else {
            // 继续去抖
            psDebounce->u8LastCC1Match = sCCStatus.cc1Match;
            psDebounce->u8LastCC2Match = sCCStatus.cc2Match;
            
            psDebounce->bDebouncing = HV_TRUE;
            psDebounce->u8TimerId = PDTimer_Start(
                TYPEC_CC_DEBOUNCE_TIME_MS,
                TypeC_CCDebounce_TimerCB,
                u8PortNum,
                (UINT8)SET_TO_ZERO);
        }
    }
}

// CC 去抖动处理
static BOOL TypeC_CCDebounce(UINT8 u8PortNum, const TypeC_CCStatus *psCCStatus)
{
    TypeC_CCDebounce_T *psDebounce = &s_CCDebounce[u8PortNum];

    // 2. 添加 CC 电平异常判断
#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_OFF)
    if ((psCCStatus->cc1AdcIn > TYPEC_CC_ABNORMAL_THR) || (psCCStatus->cc2AdcIn > TYPEC_CC_ABNORMAL_THR))
    {
        DEBUG_PRINT_PORT_STR(psCCStatus->cc1AdcIn<<16 | psCCStatus->cc2AdcIn, "Abnormal CC voltage detected\r\n");
        return HV_FALSE;
    }
#endif

    // 检查状态是否发生变化
    if ((psDebounce->u8LastCC1Match != psCCStatus->cc1Match) ||
        (psDebounce->u8LastCC2Match != psCCStatus->cc2Match)) {

        // 保存新状态
        psDebounce->u8LastCC1Match = psCCStatus->cc1Match;
        psDebounce->u8LastCC2Match = psCCStatus->cc2Match;
        DEBUG_PRINT_PORT_STR(psCCStatus->cc1AdcIn<<24 | psCCStatus->cc2AdcIn<<16 | psCCStatus->cc1Match<<8 | psCCStatus->cc2Match,
            "TypeC_CCDebounce cc1AdcIn cc2AdcIn cc1Match cc2Match\r\n");
    
        // 如果已经在去抖,重启定时器
        if (psDebounce->bDebouncing) {
            PDTimer_Kill(psDebounce->u8TimerId);
        } else {
            // 首次去抖,初始化计数
            psDebounce->u8DebounceCount = 0;
        }
        
        // 启动去抖定时器
        psDebounce->bDebouncing = HV_TRUE;
        psDebounce->u8TimerId = PDTimer_Start(
            TYPEC_CC_DEBOUNCE_TIME_MS,
            TypeC_CCDebounce_TimerCB,
            u8PortNum,
            (UINT8)SET_TO_ZERO);
            
        return HV_TRUE;
    }
    
    // 如果在去抖过程中,继续等待
    if (psDebounce->bDebouncing) {
        return HV_TRUE; 
    }

    return HV_FALSE;
}

static VOID TypeC_CCDetIntHandleFunc(UINT8 u8PortNum, UINT32 u32CCPwrDet)
{
    UINT8 u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK);
    u8RegVal &= UPD_PWR_DET_CC_ADCIN_CHG_MASK;

    // Get CC status
    TypeC_CCStatus sCCStatus = {0};
    TypeC_GetCCStatus(u8PortNum, &sCCStatus);

    // Handle CC detection interrupt
    if(u8RegVal & (UPD_PWR_DET_CC1_ADCIN_CHG_MASKBIT | UPD_PWR_DET_CC2_ADCIN_CHG_MASKBIT))
    {
        TypeC_CCDebounce(u8PortNum, &sCCStatus);
    }
}

void TypeC_CCDetHandleFunc(UINT8 u8PortNum)
{
    // 1. 使用结构体封装 CC 状态
    TypeC_CCStatus sCCStatus = {0};
    TypeC_GetCCStatus(u8PortNum, &sCCStatus);

    // 2. 记录调试信息
    DEBUG_PRINT_PORT_STR(((UINT32)u8PortNum<<16) | (sCCStatus.cc1AdcIn<<8) | sCCStatus.cc2AdcIn,
                            "TypeC_CCDetHandleFunc CC ADC Values\r\n");
    DEBUG_PRINT_PORT_STR(((UINT32)u8PortNum<<16) | (sCCStatus.cc1Match<<8) | sCCStatus.cc2Match,
                            "CC Match Status\r\n");

    // 3. 更新控制器状态
    gasTypeCcontrol[u8PortNum].u8CC1MatchISR = sCCStatus.cc1Match;
    gasTypeCcontrol[u8PortNum].u8CC2MatchISR = sCCStatus.cc2Match;
}

static VOID TypeC_CCUpdateMatchISR(UINT8 u8PortNum)
{
    TypeC_CCDebounce_T *psDebounce = &s_CCDebounce[u8PortNum];

    // 1. 使用结构体封装 CC 状态
    TypeC_CCStatus sCCStatus = {0};
    TypeC_GetCCStatus(u8PortNum, &sCCStatus);

    // 2. 记录调试信息
    DEBUG_PRINT_PORT_STR(((UINT32)u8PortNum<<16) | (sCCStatus.cc1AdcIn<<8) | sCCStatus.cc2AdcIn,
                         "TypeC_CCUpdateMatchISR CC ADC Values\r\n");
    DEBUG_PRINT_PORT_STR(((UINT32)u8PortNum<<16) | (sCCStatus.cc1Match<<8) | sCCStatus.cc2Match,
                         "CC Match Status\r\n");

    // 3. 更新psDebounce cc match状态
    psDebounce->u8LastCC1Match = sCCStatus.cc1Match;
    psDebounce->u8LastCC2Match = sCCStatus.cc2Match;
}

void TypeC_HandleISR (UINT8 u8PortNum)
{
    UINT32 u32CCPwrDet = 0;
    UINT8 u8ChannleBusy = 0;

#if(HV_TRUE == INCLUDE_PD_DRP)
    UINT8 u8MiscDet = 0;

    u8MiscDet = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RO_MISC_IRQFLAG);
    if (u8MiscDet)
    {
        /* clear the CC change flag */
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RO_MISC_IRQFLAG, UPD_MISC_DRP_DONE_MASKBIT);
        if (u8MiscDet & UPD_MISC_DRP_DONE_MASKBIT)
        {
            gasTypeCcontrol[u8PortNum].u8DRPStsISR |= TYPEC_DRP_DONE_INTERRUPT;
        }
    }
#endif
    //u8CCPwrDet = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RO_PWR_DET_IRQFLAG);
    u32CCPwrDet = HV_R32(STANDBY_USB_TYPEC_0_00_0C);

    if (u32CCPwrDet)
    {
        /* clear the CC change flag */
        //Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RO_PWR_DET_IRQFLAG, u8CCPwrDet);
        //HV_W32_FIELD_EX(STANDBY_USB_TYPEC_0_00_0C, 0x00, REG_00_RO_2C0D_IRQ_PWR_DET, u8CCPwrDet);
        HV_W32(STANDBY_USB_TYPEC_0_00_0C, u32CCPwrDet);
        TypeC_CCDetIntHandleFunc(u8PortNum, u32CCPwrDet);
    }

    u8ChannleBusy = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RO_RX_IRQFLAG);
    if (u8ChannleBusy & UPD_RX_CHANNEL_BUSY_MASKBIT)
    {
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RO_RX_IRQFLAG, UPD_RX_CHANNEL_BUSY_MASKBIT);
        //Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
    }
}

static UINT16 u16VbusCounts = 0;



VOID TypeC_VBUSCheck_TimerCB (UINT8 u8PortNum, UINT8 u8VbusValue)
{
    gasTypeCcontrol[u8PortNum].u8VBUSCheckTmrID = MAX_CONCURRENT_TIMERS;

    DEBUG_PRINT_PORT_STR(u8VbusValue, "VBUS stable u16VbusINA\r\n");
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_TYPEC_VBUS_VALUE, u8VbusValue);

    if (TYPEC_VSAFE_0V_MATCH_VAL == u8VbusValue)
    {
        if (DPM_GET_CURRENT_POWER_ROLE(u8PortNum) != PD_ROLE_SOURCE)
        {
            if ((TYPEC_ATTACHED_SNK == gasTypeCcontrol[u8PortNum].u8TypeCState) &&
                (!DPM_IS_HARDRESET_IN_PROGRESS(u8PortNum) || (DPM_IS_HARDRESET_IN_PROGRESS(u8PortNum) && UPD_FSM_STATE_ATTACHED_SNK != u8GetTypecFSMState(u8PortNum))) &&
                (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)))
            {
                /*Setting the flag that VBUS has gone below VSinkDisconnect*/
                DEBUG_PRINT_PORT_STR (u8PortNum, "Hv_PSF_PollingVBUS sink disconnect for vbus 0V.\r\n");
                HV_LOG_INFO(TYPEC,"-----sink disconnect port=%d, vbus=%d-----", u8PortNum, HV_PSF_HOOK_POLLING_READ_VBUS());

                if ((TYPEC_ATTACHED_SNK == gasTypeCcontrol[u8PortNum].u8TypeCState) && \
                        (TYPEC_ATTACHED_SNK_RUN_SM_SS == gasTypeCcontrol[u8PortNum].u8TypeCSubState))
                {
                    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS.\r\n");
                    gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS;
                }
            }
        }
    }
}

/**
 * @brief Removes the unnecessary call to TypeC_ConfigureVBUSThr for VBUS detection.
 *
 * In the current implementation, VBUS detection is performed using software polling
 * via the Hv_PSF_PollingVBUS function. The current architecture does not support
 * hardware interrupt-based VBUS detection. As a result, the TypeC_ConfigureVBUSThr
 * function call is no longer required and should be removed.
 */
void Hv_PSF_PollingVBUS (UINT8 u8PortNum)
{
    UINT16 u16VbusINA = 0;
    UINT8 u8IntStsISR = 0;

    // 检查是否启用了 VBUS 比较器
    if (!gasTypeCcontrol[u8PortNum].u8Typec_VbusCompSta) {
        return;
    }

    // 读取当前 VBUS 电压
    u16VbusINA = HV_PSF_HOOK_POLLING_READ_VBUS();

    // 如果是第一次读取，初始化 u16VbusINAPre 并设置 VBUS 值
    if (u16VbusINAPre[u8PortNum] == TYPEC_VBUS_THR_VAL_INIT) {
        u16VbusINAPre[u8PortNum] = u16VbusINA;
#if TYPEC_VBUS_ENABLE_DEBOUNCE
        PDTimer_Kill(gasTypeCcontrol[u8PortNum].u8VBUSCheckTmrID);
        gasTypeCcontrol[u8PortNum].u8VBUSCheckTmrID = MAX_CONCURRENT_TIMERS;
#endif
        DEBUG_PRINT_PORT_STR(u16VbusINA, "Start polling VBUS: u16VbusINA\r\n");
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_TYPEC_VBUS_VALUE, 
            (UINT8)(TYPEC_GET_VBUS_VAL_IN_MV_FROM_THRX(u16VbusINA) / 100));
        return;
    }

    // 检查 VBUS 是否发生变化
    if (u16VbusINA != u16VbusINAPre[u8PortNum] && u16VbusINA != TYPEC_VBUS_THR_VAL_UNDEF) {
        DEBUG_PRINT_PORT_STR((u16VbusINAPre[u8PortNum] << 16) | u16VbusINA, 
            "VBUS changed: pre and u16VbusINA\r\n");

        // 更新前一个 VBUS 值
        u16VbusINAPre[u8PortNum] = u16VbusINA;
#if TYPEC_VBUS_ENABLE_DEBOUNCE
        // 启动定时器以检查 VBUS 稳定性
        PDTimer_Kill(gasTypeCcontrol[u8PortNum].u8VBUSCheckTmrID);
        gasTypeCcontrol[u8PortNum].u8VBUSCheckTmrID = PDTimer_Start(
            TYPEC_VBUS_CHECK_TIMEOUT_MS, 
            TypeC_VBUSCheck_TimerCB, 
            u8PortNum, 
            (UINT8)(TYPEC_GET_VBUS_VAL_IN_MV_FROM_THRX(u16VbusINA) / 100));
#else
        // 设置新的 VBUS 值
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_TYPEC_VBUS_VALUE, 
            (UINT8)(TYPEC_GET_VBUS_VAL_IN_MV_FROM_THRX(u16VbusINA) / 100));
        if (TYPEC_VSAFE_0V_MATCH_VAL == u16VbusINA)
        {
            if (DPM_GET_CURRENT_POWER_ROLE(u8PortNum) != PD_ROLE_SOURCE)
            {
                /* 对于作为sink角色，VBUS变为0后，需要执行disconnect的流程， 除了这种情况：
                    双方在hard reset处理中。
                    在BIST mode测试完后， 会发起hard reset， 但是之后 source(tester)假如没有把vbus拉到5V的话， hard reset的标志
                    就没有被清除。需要避免这个情况 */
                /* Verifies whether VBUS Drop is due to Source detach*/
                if ((TYPEC_ATTACHED_SNK == gasTypeCcontrol[u8PortNum].u8TypeCState) &&
                    (!DPM_IS_HARDRESET_IN_PROGRESS(u8PortNum) || (DPM_IS_HARDRESET_IN_PROGRESS(u8PortNum) && UPD_FSM_STATE_ATTACHED_SNK != u8GetTypecFSMState(u8PortNum))) &&
                    (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)))
                {
                    /*Setting the flag that VBUS has gone below VSinkDisconnect*/
                    DEBUG_PRINT_PORT_STR (u8PortNum, "Hv_PSF_PollingVBUS sink disconnect for vbus 0V.\r\n");
                    HV_LOG_INFO(TYPEC,"-----sink disconnect port=%d, vbus=%d-----", u8PortNum, HV_PSF_HOOK_POLLING_READ_VBUS());
    
                    if ((TYPEC_ATTACHED_SNK == gasTypeCcontrol[u8PortNum].u8TypeCState) && \
                            (TYPEC_ATTACHED_SNK_RUN_SM_SS == gasTypeCcontrol[u8PortNum].u8TypeCSubState))
                    {
                        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS.\r\n");
                        gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_PD_DEB_TIMEOUT_SS;
                    }
                }
            }
        }
#endif
    }
}

/*******************************************************************************************/
/*********************************TypeC CC Support Functions**************************************/
/*******************************************************************************************/

void TypeC_SetCCDebounceVariable (UINT8 u8PortNum, UINT8 u8Pwrrole)
{
    UINT8 u8CCDebMatch = gasTypeCcontrol[u8PortNum].u8CCDebMatch;
    UINT8 u8CCSrcSnkMatch = gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch;

    UINT8 u8vRaTh = 0;
    UINT8 u8vRdTh = 0;
    UINT8 u8vSinkRdTh = 0;

    switch (u8Pwrrole)
    {
#if  (HV_TRUE == INCLUDE_PD_SINK)
        case TYPEC_UFP:
        {
            u8CCDebMatch = (TYPEC_CC_THRES0_MATCH | TYPEC_CC_THRES2_MATCH \
                            | TYPEC_CC_THRES4_MATCH | TYPEC_CC_THRES7_MATCH);
            u8vSinkRdTh = TYPEC_SINK_CON_THRE_VAL;//TYPEC_CC_THR3_VAL;
            break;
        }
#endif


#if  (HV_TRUE == INCLUDE_PD_SOURCE)
        case TYPEC_DFP_DEFAULT_CURRENT:
        {
            /*DFP_ACT_DEF(CC_THR0),DFP_UFP_DEF(CC_THR5)*/
            u8CCDebMatch = (TYPEC_CC_THRES0_MATCH | TYPEC_CC_THRES5_MATCH);

            /*u8CCSrcSnkMatch is useful for finding which CC line has Sink attachment*/
            u8CCSrcSnkMatch = (TYPEC_CC_THRES5_MATCH);

            u8vRaTh = TYPEC_CC_THR0_VAL;
            u8vRdTh = TYPEC_CC_THR5_VAL;
            break;
        }

        case TYPEC_DFP_1A5_CURRENT:
        {
            /*DFP_ACT_1A5(CC_THR1),DFP_UFP_1A5(CC_THR5)*/
            u8CCDebMatch = (TYPEC_CC_THRES1_MATCH | TYPEC_CC_THRES5_MATCH);

            /*u8CCSrcSnkMatch is useful for finding which CC line has Sink attachment*/
            u8CCSrcSnkMatch = (TYPEC_CC_THRES5_MATCH);

            u8vRaTh = TYPEC_CC_THR1_VAL;
            u8vRdTh = TYPEC_CC_THR5_VAL;
            break;
        }

        case TYPEC_DFP_3A0_CURRENT:
        {
            /*DFP_ACT_3A0 (CC_THR3),DFP_UFP_3A0 (CC_THR6)*/
            u8CCDebMatch = (TYPEC_CC_THRES3_MATCH | TYPEC_CC_THRES6_MATCH);

            /*u8CCSrcSnkMatch is useful for finding which CC line has Sink attachment*/
            u8CCSrcSnkMatch = (TYPEC_CC_THRES6_MATCH);

            u8vRaTh = TYPEC_CC_THR3_VAL;
            u8vRdTh = TYPEC_CC_THR6_VAL;
            break;
        }
#endif /*INCLUDE_PD_SOURCE*/

        default:
            break;
    }


    if (TYPEC_UFP != u8Pwrrole)
    {
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RA_THRD, u8vRaTh);
        // Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CC_RD_THRD, u8vRdTh);
    }
    else
    {
#if (HV_TYPEC_CONFIG_TYPEC_MODE != TYPEC_MODE_SINK)
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_SINK_CON_TH, u8vSinkRdTh);
#else
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_SINK_CON_TH, 0x30);
#endif
    }

    gasTypeCcontrol[u8PortNum].u8CCDebMatch = u8CCDebMatch;
    gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch = u8CCSrcSnkMatch;

}
void TypeC_ConfigCCComp (UINT8 u8PortNum, UINT8 u8ConfigVal)
{
#if (HV_FALSE == TYPEC_CC_VOLCHG_USE_POLLING)
    UINT8 u8RegVal;
#if TYPEC_CC_INT_ONLY_USE_ADC_IN
    u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK);
    u8RegVal &= ~UPD_PWR_DET_CC_ADCIN_CHG_MASK;
    u8RegVal |= (u8ConfigVal << UPD_PWR_DET_CC_ADCIN_CHG_POS);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK, u8RegVal);
#else
    u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK);
    u8RegVal &= ~UPD_PWR_DET_CC_ADCIN_CHG_MASK;
    u8RegVal |= (u8ConfigVal << UPD_PWR_DET_CC_ADCIN_CHG_POS);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_PWR_DET_IRQMASK, u8RegVal);

    u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_CCVOL_DET_IRQMASK);
    u8RegVal &= ~(UPD_CCVOL_DET_CC_CHG_MASK);
    u8RegVal |= (u8ConfigVal << UPD_CCVOL_DET_CC_CHG_POS);
    Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CCVOL_DET_IRQMASK, u8RegVal);
#endif

#else
    gasTypeCcontrol[u8PortNum].u8TypeC_CCCompSta = u8ConfigVal;
#endif
}
#if(HV_TRUE == INCLUDE_PD_DRP)
void TypeC_DRPSetCCSampleEnable (UINT8 u8PortNum, UINT8 u8RpCurrent)
{

}

void TypeC_DRPSetPRSwapInflow(UINT32 u8PortNum, UINT8 u8PrInflow)
{
    /*the PR swap inflow is active only in attach.snk state.*/
    if (u8PrInflow)
    {
        if (TYPEC_ORIENTATION_CC2 == TYPEC_GET_CC_ORIENTATION_STS(u8PortNum))
        {
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG, UPD_CC_SEL_PLUG_MASK | UPD_PLUG_APP_MODE_MASK);
        }
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_INFLOW);
    }
    else
    {
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG, UPD_CC_SEL_PLUG_MASK | UPD_PLUG_APP_MODE_MASK);
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_INFLOW);
    }
}

void TypeC_DRPSetPRSwapPsRdy(UINT32 u8PortNum, UINT8 u8PrPsRdy)
{
    /*the sink will trans to source if receiving or sending ps rdy*/
    if (u8PrPsRdy)
    {
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_RDY);
    }
    else
    {
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_RDY);
    }
}

void TypeC_DRPSetPRSwapInAccept(UINT32 u8PortNum, UINT8 u8PrAccept)
{
    /*the source will trans to source if receiving or sending accept*/
    if (u8PrAccept)
    {
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_ACCEPT);
    }
    else
    {
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_DRP_CONFIG, UPD_DRP_CONFIG_PR_SWAP_ACCEPT);
    }
}

#endif /*INCLUDE_PD_DRP*/

void TypeC_SetCCSampleEnable (UINT8 u8PortNum, UINT8 u8CCEnablePins)
{
    //gasTypeCcontrol[u8PortNum].u8TypeC_CCCompSta = u8ConfigVal;
}

void TypeC_SetCCPowerRole(UINT8 u8PortNum, UINT8 u8PowerRole, UINT8 u8ConfigVal, UINT8 u8CCPin)
{
    if (PD_ROLE_SINK == u8PowerRole)
    {
        //disable the rp
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, (UPD_CC_RPRD_RPEN_CC1 | UPD_CC_RPRD_RPEN_CC2));
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, (UPD_CC_RPRD_RDEN_CC1 | UPD_CC_RPRD_RDEN_CC2));
        if (u8CCPin & TYPEC_ENABLE_CC1)
        {
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RDEN_CC1);
        }
        if (u8CCPin & TYPEC_ENABLE_CC2)
        {
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RDEN_CC2);
        }

        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_EXTEN_CTRL1, UPD_EXTEN_CTRL1_PWR_ROLE_SEL);

        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG,
                            UPD_CC_RP_EN_MASK);                            //to confirm
    }
    else if (PD_ROLE_SOURCE == u8PowerRole)
    {
        //disable the rd
        Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, (UPD_CC_RPRD_RDEN_CC1 | UPD_CC_RPRD_RDEN_CC2));
        if (u8CCPin & TYPEC_ENABLE_CC1 && u8ConfigVal != 0)
        {
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RPEN_CC1);
        }
        else
        {
            Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RPEN_CC1);
        }

        if (u8CCPin & TYPEC_ENABLE_CC2 && u8ConfigVal != 0)
        {
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RPEN_CC2);
        }
        else
        {
            Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CC_RPRD_SET, UPD_CC_RPRD_RPEN_CC2);
        }

        if (u8ConfigVal != 0)
        {

        }

        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_EXTEN_CTRL1, UPD_EXTEN_CTRL1_PWR_ROLE_SEL);        //reg_cc_rp_en
        Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_PLUG_FLIP_DET_CONFIG, UPD_CC_RP_EN_MASK);                         //to confirm
    }
    else
    {
        /* Do Nothing */
    }
}
void TypeC_SetCCDeviceRole (UINT8 u8PortNum, UINT8 u8DevRole)            //no use in drp
{
    /* Setting Port Device Role */
    UINT8    u8RegVal = 0;
    u8RegVal = Hv_Typec_RegReadByte(u8PortNum, UPD_REG_RW_CONFIG_LOW);
    u8RegVal &= ~(UPD_CONFIG_LOW_PWRROLE_MASK);
    if (u8DevRole == PD_ROLE_UFP)
    {
        u8RegVal |= (1 << UPD_CONFIG_LOW_PWRROLE_POS);
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CONFIG_LOW, u8RegVal);            //0: DFP, 1: UFP, 2:DRP
    }
    else if (u8DevRole == PD_ROLE_DFP)
    {
        u8RegVal |= (0 << UPD_CONFIG_LOW_PWRROLE_POS);
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CONFIG_LOW, u8RegVal);            //0: DFP, 1: UFP, 2:DRP
    }
    else if (u8DevRole == PD_ROLE_DRP)
    {
        u8RegVal |= (2 << UPD_CONFIG_LOW_PWRROLE_POS);
        Hv_Typec_RegWriteByte(u8PortNum, UPD_REG_RW_CONFIG_LOW, u8RegVal);            //0: DFP, 1: UFP, 2:DRP
    }
    else
    {
        /* Do Nothing */
    }
}
#if (HV_TRUE == INCLUDE_PD_SOURCE)
void TypeC_SetCCDefaultRpValue (UINT8 u8PortNum)
{
    UINT16 u16Data;

    u16Data = DPM_GET_CONFIGURED_SOURCE_RP_VAL(u8PortNum);

    /*Setting Rp Current Source as user given and Rd as Open disconnect in both CC1 and CC2*/
    TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, (UINT8) u16Data, TYPEC_ENABLE_CC1_CC2);

    /*Setting the u8CCDebMatch and u8CCSrcSnkMatch variable accordingly as per Rp Value*/
    TypeC_SetCCDebounceVariable (u8PortNum, (UINT8) u16Data);

    /*Resetting the CC Debounce clear enable,CC Match Enable,CC Sample Enable register*/
    TypeC_SetCCSampleEnable (u8PortNum, TYPEC_ENABLE_CC1_CC2);

    /*Setting user given Rp Value as Current Rp Value in CurrentRpVal bit of u8PortSts variable*/
    gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;
    gasTypeCcontrol[u8PortNum].u8PortSts |= (u16Data << TYPEC_CURR_RPVAL_POS);
}
#endif /*INCLUDE_PD_SOURCE*/

#if (HV_TRUE == INCLUDE_PD_SINK)
void TypeC_DecodeCCSourceRpValue (UINT8 u8PortNum)
{
    /*Assigning the structure variables to local variables to reduce the code size as
    accessing the structure members takes lot of code*/
    UINT8 u8PortSts = gasTypeCcontrol[u8PortNum].u8PortSts;

    UINT8 u8CCSrcSnkMatch = gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch;

    /*Clearing the Current Rp Value of Source*/
    u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;

    switch (gasTypeCcontrol[u8PortNum].u8CC1MatchISR ^ gasTypeCcontrol[u8PortNum].u8CC2MatchISR)
    {
        case TYPEC_DFP_DEF_ATT:
        case (TYPEC_DFP_DEF_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        {
            /*Setting the Current Rp Value of Source as Default Current*/
            u8PortSts |= (TYPEC_RP_DEFAULT_CURRENT << TYPEC_CURR_RPVAL_POS);

            u8CCSrcSnkMatch = TYPEC_DFP_DEF_ATT;
            break;
        }

        case TYPEC_DFP_1A5_ATT:
        case (TYPEC_DFP_1A5_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        {
            /*Setting the Current Rp Value of Source as 1.5A@5V */
            u8PortSts |= (TYPEC_RP_CURRENT_15 << TYPEC_CURR_RPVAL_POS);

            u8CCSrcSnkMatch = TYPEC_DFP_1A5_ATT;
            break;
        }

        case TYPEC_DFP_3A0_ATT:
        case (TYPEC_DFP_3A0_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        {
            /*Setting the Current Rp Value of Source as 3.0A@5V */
            u8PortSts |= (TYPEC_RP_CURRENT_30 << TYPEC_CURR_RPVAL_POS);

            u8CCSrcSnkMatch = TYPEC_DFP_3A0_ATT;

            break;
        }

        default:
        {
            break;
        }
    }

    gasTypeCcontrol[u8PortNum].u8PortSts = u8PortSts;
    gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch = u8CCSrcSnkMatch;
}
#endif/*INCLUDE_PD_SINK*/
/*******************************************************************************************/
/*********************************TypeC VCONN Support Functions**************************************/
/*******************************************************************************************/
VOID TypeC_EnabDisVCONN (UINT8 u8PortNum, UINT8 u8EnableDisable)
{
    UINT32 u32Cnt = 0;
    UINT32 u8CCAdcIn = 0;
    UINT8 u8VCONNSource = 0;

    /*Setting CC Comparator OFF*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);
    if (TYPEC_VCONN_DISABLE == u8EnableDisable)
    {
        gasTypeCcontrol[u8PortNum].u8CCDebMatch = (TYPEC_CC_THRES0_MATCH);

        DEBUG_PRINT_PORT_STR (gasTypeCcontrol[u8PortNum].u8IntStsISR,"TYPEC: Disable VCONN, u8IntStsISR\r\n");

        // 确定当前 VCONN 来源
        u8VCONNSource = (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK) == TYPEC_VCONN_SOURCE_CC1
                            ? TYPEC_ENABLE_CC1
                            : TYPEC_ENABLE_CC2;

        DEBUG_PRINT_PORT_STR(u8PortNum, u8VCONNSource == TYPEC_ENABLE_CC1 ? "Disabling VCONN on CC1\r\n" : "Disabling VCONN on CC2\r\n");
        /* Disable VCONN and initiate discharge */
        if (u8VCONNSource == TYPEC_ENABLE_CC1)
        {
            HV_PSF_HOOK_VCONN_CC1_PWR_SET(u8PortNum, HV_FALSE);
            HV_PSF_HOOK_VCONN_CC1_DISCHARGE_SET(u8PortNum, HV_TRUE);
        }
        else if (u8VCONNSource == TYPEC_ENABLE_CC2)
        {
            HV_PSF_HOOK_VCONN_CC2_PWR_SET(u8PortNum, HV_FALSE);
            HV_PSF_HOOK_VCONN_CC2_DISCHARGE_SET(u8PortNum, HV_TRUE);
        }

        /* Poll until VCONN discharge is complete or timeout */
        while (u32Cnt++ < TYPEC_VCONN_OFF_TIMEOUT)
        {
            u8CCAdcIn = (UINT8)(((Hv_Typec_RegReadWord(u8PortNum, 
                (u8VCONNSource == TYPEC_ENABLE_CC1) ? UPD_REG_RW_CC1_ADC_IN : UPD_REG_RW_CC2_ADC_IN)) & 0xFFF) >> 4);
            if (u8CCAdcIn < TYPEC_VCONN_VSAFE0V_THRESH)
            {
                break;
            }
            Hv_Vos_Delayus(1000);
        }

        // 放电完成处理
        gasTypeCcontrol[u8PortNum].u8IntStsISR &= ~TYPEC_VCONN_SOURCE_MASK;
        gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus &= ~(DPM_PORT_VCONN_ENABLE_STATUS);
        TypeC_OnVCONNDISCHComplete (u8PortNum);

        DEBUG_PRINT_PORT_STR((u8PortNum << 24) | (u8CCAdcIn << 16) | u32Cnt, "TYPEC: VCONN discharge complete\r\n");
    }
    else
    {
        UINT8 u8VCONN1Enable = HV_FALSE;
        DEBUG_PRINT_PORT_STR((u8PortNum << 24) | gasTypeCcontrol[u8PortNum].u8PortSts<<16 | (gasTypeCcontrol[u8PortNum].u8CC1MatchISR << 8) | gasTypeCcontrol[u8PortNum].u8CC2MatchISR,
            "TYPEC: Enable VCONN u8PortSts u8CC1MatchISR u8CC2MatchISR\r\n");

        /* Determine which CC pin should source VCONN */
        if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
        {
            u8VCONN1Enable = (gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) &&
                             (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_PWDCABLE_PRES_MASK);
        }
        else
        {
            u8VCONN1Enable = gasTypeCcontrol[u8PortNum].u8CC1MatchISR < gasTypeCcontrol[u8PortNum].u8CC2MatchISR;
        }

        /* Enable VCONN on the appropriate pin */
        if (u8VCONN1Enable)
        {
            DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: Enable VCONN on CC1\r\n");
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_VCONN1_ON_REQ;
            HV_PSF_HOOK_VCONN_CC1_PWR_SET(u8PortNum, HV_TRUE);
        }
        else
        {
            DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: Enable VCONN on CC2\r\n");
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_VCONN2_ON_REQ;
            HV_PSF_HOOK_VCONN_CC2_PWR_SET(u8PortNum, HV_TRUE);
        }

        /* Poll until VCONN is stable or timeout */
        while (u32Cnt++ < TYPEC_VCONN_ON_TIMEOUT)
        {
            u8CCAdcIn = (UINT8)(((Hv_Typec_RegReadWord(u8PortNum,
                (u8VCONN1Enable ? UPD_REG_RW_CC1_ADC_IN : UPD_REG_RW_CC2_ADC_IN)) & 0xFFF) >> 4));
            if (u8CCAdcIn >= TYPEC_VCONN_VSAFE5V_THRESH)
            {
                break;
            }
            Hv_Vos_Delayus(1000);
        }

        // 超时处理
        if(u32Cnt >= TYPEC_VCONN_ON_TIMEOUT)
        {
            DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: VCONN ON Timeout\r\n");
            // 处理超时错误
            if (u8VCONN1Enable)
            {
                HV_PSF_HOOK_VCONN_CC1_PWR_SET(u8PortNum, HV_FALSE);
            }
            else
            {
                HV_PSF_HOOK_VCONN_CC2_PWR_SET(u8PortNum, HV_FALSE);
            }
        }

        if (gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN_ON_REQ_MASK)
        {
            /* VCONN ON OFF是采用轮询的方式， 没有使用中断的方式， 所以在VCONN ON 或OFF complete后要重新刷下一下CC */
            TypeC_CCDetHandleFunc(u8PortNum);

            TypeC_VCONNOnIntrHandler (u8PortNum);
        }
        DEBUG_PRINT_PORT_STR((u8PortNum << 24) | (u8CCAdcIn << 16) | u32Cnt, "TYPEC: VCONN enable complete\r\n");
    }
    /*Setting CC Comparator to sample both the CC1 and CC2*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);
}

/*******************************************************************************************/
/*********************************Type C modules Interrupt Functions**************************************/
/**********************************************************************************************/
VOID TypeC_VCONNOnIntrHandler (UINT8 u8PortNum)
{
    DEBUG_PRINT_PORT_STR(gasTypeCcontrol[u8PortNum].u8PortSts,"TypeC_VCONNOnIntrHandler: u8PortSts\r\n");
    DEBUG_PRINT_PORT_STR(gasTypeCcontrol[u8PortNum].u8CC1MatchISR,"TypeC_VCONNOnIntrHandler: u8CC1MatchISR\r\n");
    DEBUG_PRINT_PORT_STR(gasTypeCcontrol[u8PortNum].u8CC2MatchISR,"TypeC_VCONNOnIntrHandler: u8CC2MatchISR\r\n");
    DEBUG_PRINT_PORT_STR(gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch,"TypeC_VCONNOnIntrHandler: u8CCSrcSnkMatch\r\n");

    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        /*VCONN Enabled in CC1 and Sink Attached in CC2*/
        if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN1_ON_REQ) && \
            (SET_TO_ZERO == gasTypeCcontrol[u8PortNum].u8CC1MatchISR) &&
              (gasTypeCcontrol[u8PortNum].u8CC2MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch))
        {
            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_VCONN_SOURCE_CC1;

            DEBUG_PRINT_PORT_STR(u8PortNum,"TYPEC: VCONN Enabled in CC1\r\n");
        }
         /*VCONN Enabled in CC2 and Sink Attached in CC1*/
        else if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN2_ON_REQ) && \
            (SET_TO_ZERO == gasTypeCcontrol[u8PortNum].u8CC2MatchISR) &&
            (gasTypeCcontrol[u8PortNum].u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch))
        {
            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_VCONN_SOURCE_CC2;

            DEBUG_PRINT_PORT_STR(u8PortNum,"TYPEC: VCONN Enabled in CC2\r\n");
        }
        else
        {
            /* Do Nothing */
        }
    }
    else
    {
        /* During a Sink initiated VCONN Swap, Sink port which is presently not
           the VCONN Source would drive the VCONN and wait for VCONN ON interrupt.
           Before the VCONN Swap message reaches the Source port, Source port will set
           the Rp value to SINK_TX_NG (1.5A@5V) for the Sink to not initiate
           any AMS. During this scenario, both Rp change interrupt and VCONN ON interrupt
           triggers at the same time. So, decode the current Rp value before handling
           VCONN ON Interrupt */
        #if (HV_TRUE == INCLUDE_PD_SINK)
        //DEBUG_PRINT_PORT_STR(u8PortNum,">>> TypeC_DecodeCCSourceRpValue called by TypeC_VCONNOnIntrHandler\r\n");
        TypeC_DecodeCCSourceRpValue(u8PortNum);
        #endif

        /*VCONN Enabled in CC1 and Source Attached in CC2*/
        if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN1_ON_REQ) && \
            (TYPEC_SNK_CCTHRES_VCONN_ON == gasTypeCcontrol[u8PortNum].u8CC1MatchISR) &&
            ((gasTypeCcontrol[u8PortNum].u8CC2MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch)))
        {
             /*Setting the u8IntStsISR variable that CC1 is the VCONN source*/
            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_VCONN_SOURCE_CC1;

            DEBUG_PRINT_PORT_STR(u8PortNum,"TYPEC: VCONN Enabled in CC1\r\n");
        }
         /*VCONN Enabled in CC2 and Source Attached in CC1*/
        else if ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_VCONN2_ON_REQ) && \
            (TYPEC_SNK_CCTHRES_VCONN_ON == gasTypeCcontrol[u8PortNum].u8CC2MatchISR) &&
             (gasTypeCcontrol[u8PortNum].u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch))
        {
             /*Setting the u8IntStsISR variable that CC2 is the VCONN source*/
            gasTypeCcontrol[u8PortNum].u8IntStsISR |= TYPEC_VCONN_SOURCE_CC2;

            DEBUG_PRINT_PORT_STR(u8PortNum,"TYPEC: VCONN Enabled in CC2\r\n");
        }
        else
        {
            /* Do Nothing */
        }
    }
    /*Handle only the CC interrupt for VCONN_ON event.CC interrupts for detach
    event or others should be handled in either SrcIntr Handler or SnkIntr Handler function*/
    if (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK)
    {
         /*Clearing the VCONN ON Request mask if VCONN has turned ON*/
         gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_VCONN_ON_REQ_MASK;

         /* Setting the Port Connect Status to indicate VCONN is enabled */
         gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus |= DPM_PORT_VCONN_ENABLE_STATUS;
    }
}

void TypeC_CCDRPIntrHandler (UINT8 u8PortNum)
{
    /*Handling the state changes for CC and DRP interrupts in foreground and not in ISR to
    avoid variable corruption*/

#if(HV_TRUE == INCLUDE_PD_DRP)
    TypeC_DRPIntrHandler (u8PortNum);
#endif

    if (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_CCINT_STATUS_MASK)
    {
        HV_PSF_HOOK_DISABLE_GLOBAL_INTERRUPT();
        switch (gasTypeCcontrol[u8PortNum].u8TypeCState)
        {
#if (HV_TRUE == INCLUDE_PD_SOURCE)
            case TYPEC_UNATTACHED_SRC:
            case TYPEC_ATTACHWAIT_SRC:
            case TYPEC_ATTACHED_SRC:
            {
#if(INCLUDE_PD_ALT_MODE == HV_TRUE)
                gasCfgStatusData.sVDMPerPortData[u8PortNum].u8SVDMIrqHpdFlag = HV_FALSE;
#endif
                TypeC_SrcIntrHandler (u8PortNum);
                break;
            }
#endif
#if (HV_TRUE == INCLUDE_PD_SINK)
            case TYPEC_UNATTACHED_SNK:
            case TYPEC_ATTACHWAIT_SNK:
            case TYPEC_ATTACHED_SNK:
            {
                TypeC_SnkIntrHandler (u8PortNum);
                break;
            }
#endif

            case TYPEC_AUDIO_ACCESSORY:
            case TYPEC_UNORIENTED_DEBUG_ACCESSORY_SRC:
            {
                /*Only the CC Detach is expected in both the above states.Hence CC interrupt leads
                to unattached state*/
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_UNATTACHED_SRC;
                break;
            }

            default:
            {
                break;
            }
        }
        /*Clearing the CC interrupt status in u8IntStsISR variable*/
        gasTypeCcontrol[u8PortNum].u8IntStsISR &= ~TYPEC_CCINT_STATUS_MASK;
        HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();
    }
}

#if(HV_TRUE == INCLUDE_PD_DRP)

static void TypeC_DRPSetCCMatchForSnkMode(UINT8 u8PortNum)
{
    UINT8 u8CC1AdcIn = 0;
    UINT8 u8CC2AdcIn = 0;
    UINT8 u8CC1Match = 0;
    UINT8 u8CC2Match = 0;
    UINT8 u8CCDebMatch = 0;
    UINT32 u32RegVal = 0;

    TypeC_SetCCDebounceVariable(u8PortNum, TYPEC_UFP);

    u8CCDebMatch = gasTypeCcontrol[u8PortNum].u8CCDebMatch;

    u32RegVal = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC1_ADC_IN);
    u8CC1AdcIn = (UINT8)((u32RegVal & 0xFFF) >> 4);
    u8CC1Match = TypeC_GetCCMatch(u8PortNum, u8CC1AdcIn, u8CCDebMatch);
    u32RegVal = Hv_Typec_RegReadWord(u8PortNum, UPD_REG_RW_CC2_ADC_IN);
    u8CC2AdcIn = (UINT8)((u32RegVal & 0xFFF) >> 4);
    u8CC2Match = TypeC_GetCCMatch(u8PortNum, u8CC2AdcIn, u8CCDebMatch);

    gasTypeCcontrol[u8PortNum].u8CC1MatchISR = u8CC1Match;
    gasTypeCcontrol[u8PortNum].u8CC2MatchISR = u8CC2Match;

    TypeC_DecodeCCSourceRpValue(u8PortNum);
}

void TypeC_DRPIntrHandler (UINT8 u8PortNum)
{
    UINT8 u8Data = SET_TO_ZERO;

    if (HV_TRUE == (gasTypeCcontrol[u8PortNum].u8DRPStsISR & TYPEC_DRP_DONE_INTERRUPT))
    {
        HV_PSF_HOOK_DISABLE_GLOBAL_INTERRUPT();
        /*Get the state being advertised from DRP_CTL_HIGH register*/
        Hv_Typec_RegisterReadISR (u8PortNum, UPD_REG_RO_FSM_STATE, &u8Data, BYTE_LEN_1);

        if (UPD_FSM_STATE_ATTACHED_SNK == (u8Data & UPD_FSM_STATE_MASK))
        {
            DEBUG_PRINT_PORT_STR ((gasTypeCcontrol[u8PortNum].u8TypeCState<<8) | gasTypeCcontrol[u8PortNum].u8TypeCSubState,
                                    "DRP attached as Sink-UFP\r\n");
            /*Set power and data role status as Sink/UFP*/
            DPM_UpdatePowerRole (u8PortNum, PD_ROLE_SINK);
            DPM_UpdateDataRole (u8PortNum, PD_ROLE_UFP);

            /* 为了避免attached sink状态下收到hard reset后， vbus变为0后typec hw fsm变为3后由于偏向source而变为9（fsm变为9后会导致rp拉高，从而引起状态错乱），
               增加下面的处理：当attached snk时候， 偏向snk， attached source时候偏向source。*/
            Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_DRP_PREFERENCE);
            
            TypeC_DRPSetCCMatchForSnkMode(u8PortNum);
            /* 下面这个条件是在M310e测试CTS case中发现的， 软件状态机和硬件状态机不一致时候进行特殊处理 */
            if (TYPEC_UNATTACHED_SNK == gasTypeCcontrol[u8PortNum].u8TypeCState)
            {
                TypeC_CCDetHandleFunc(u8PortNum);
                TypeC_SnkIntrHandler(u8PortNum);
                DEBUG_PRINT_PORT_STR (DPM_GetVBUSVoltage(u8PortNum), "VBUS VOL----\r\n");
                gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_ATTACHED_SNK;
                gasTypeCcontrol[u8PortNum].u8TypeCSubState = TYPEC_ATTACHED_SNK_ENTRY_SS;

                gasPolicyEngine[u8PortNum].ePEState = ePE_SNK_STARTUP;
                gasPolicyEngine[u8PortNum].ePESubState = ePE_INVALIDSUBSTATE;

                TypeC_DRPEnDisToggle(u8PortNum, HV_FALSE);
                
                gasTypeCcontrol[u8PortNum].u8DRPStsISR &= (~TYPEC_DRP_DONE_INTERRUPT);
                HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();
                return;
            }
        }
        else if (UPD_FSM_STATE_ATTACHED_SRC == (u8Data & UPD_FSM_STATE_MASK))
        {
            DEBUG_PRINT_PORT_STR ((gasTypeCcontrol[u8PortNum].u8TypeCState<<8) | gasTypeCcontrol[u8PortNum].u8TypeCSubState,
                                    "DRP attached as Source-DFP\r\n");

            /*Set power and data role status as Source/DFP*/
            DPM_UpdatePowerRole (u8PortNum, PD_ROLE_SOURCE);

            DPM_UpdateDataRole (u8PortNum, PD_ROLE_DFP);

            Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_CONFIG_LOW, UPD_CONFIG_LOW_DRP_PREFERENCE);
            
            /**
             * If the Type-C software state machine is already in the attach wait src state,
             * and a drp done interrupt is detected while the Type-C hardware state machine
             * is in either the attach wait src or attached src state, just only continue running
             * the Type-C software state machine without calling DPM_UpdatePowerRole and 
             * DPM_UpdateDataRole. This allows the Type-C software state machine to continue 
             * its operation without restarting.
             */
            if (TYPEC_ATTACHWAIT_SRC == gasTypeCcontrol[u8PortNum].u8TypeCState)
            {
                DEBUG_PRINT_PORT_STR (u8PortNum,"u8TypeCState is in TYPEC_ATTACHWAIT_SRC\r\n");
                gasTypeCcontrol[u8PortNum].u8DRPStsISR &= (~TYPEC_DRP_DONE_INTERRUPT);
                HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();
                return;
            }
        }
        else
        {
            /*do nothing*/
        }

        gasTypeCcontrol[u8PortNum].u8TypeCState = TYPEC_INIT;
        gasTypeCcontrol[u8PortNum].u8TypeCSubState = SET_TO_ZERO;

        gasTypeCcontrol[u8PortNum].u8DRPStsISR &= (~TYPEC_DRP_DONE_INTERRUPT);
        HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();
    }
}
#endif

#if (HV_TRUE == INCLUDE_PD_SOURCE)
void TypeC_SrcIntrHandler (UINT8 u8PortNum)
{
    /*Assigning the structure variables to local variables to reduce the code size as
    accessing the structure members takes lot of code*/

    UINT8 u8TypeCState = gasTypeCcontrol[u8PortNum].u8TypeCState;
    UINT8 u8TypeCSubState = gasTypeCcontrol[u8PortNum].u8TypeCSubState;

    switch (gasTypeCcontrol[u8PortNum].u8CC1MatchISR ^ gasTypeCcontrol[u8PortNum].u8CC2MatchISR)
    {
        /*Only Powered Cable is present*/
        case TYPEC_PWD_CABLE_ATT_DEF:
        case TYPEC_PWD_CABLE_ATT_1A5:
        case TYPEC_PWD_CABLE_ATT_3A0:
        {
#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_OFF)
            /*Clearing the Powered cable presence in u8PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;

            DEBUG_PRINT_PORT_STR ((u8PortNum<<16) | u8TypeCState,"TYPEC: Powered Cable present only\r\n");

            if (TYPEC_ATTACHWAIT_SRC == u8TypeCState)
            {
                /*Kill the TCC debounce timer running already*/
                TypeC_KillTypeCTimer(u8PortNum);

                /*Move to TYPEC_UNATTACHED_SRC state  if current state is
                TYPEC_ATTACHWAIT_SRC*/
                u8TypeCState = TYPEC_UNATTACHED_SRC;
                u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
            }
            else if (TYPEC_ATTACHED_SRC == u8TypeCState)
            {
                /*Move to TYPEC_UNATTACHED_WAIT_SRC state if current state is
                TYPEC_ATTACHED_SRC. A FR_Swap from Sink to Source should
                not be considered as a detach. So, don't do anything */
                if (!((DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)) && \
                        (DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))))
                {
                    u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                    u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
                }
            }
            else
            {
                /* Do Nothing */
            }
#else

            DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: Only Powered Cable is Present in CC");
            DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 1 : 2),
                                  "\r\n");
            DEBUG_PRINT_PORT_STR ((u8TypeCState<<8) | u8TypeCSubState, "u8TypeCState u8TypeCSubState\r\n");
            
            UINT8 u8Data = SET_TO_ZERO;
            /*Get the state being advertised from DRP_CTL_HIGH register*/
            Hv_Typec_RegisterReadISR (u8PortNum, UPD_REG_RO_FSM_STATE, &u8Data, BYTE_LEN_1);

            if (TYPEC_FSM_STATE_ATTACH_WAIT_SOURCE == (u8Data & UPD_FSM_STATE_MASK) || 
                TYPEC_FSM_STATE_ATTACHED_SOURCE == (u8Data & UPD_FSM_STATE_MASK))
            {
                DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: Typec Hw State is attach_wait or attach_source, skip this process\r\n");
                break;
            }
                
            /*Setting the Powered cable presence in u8PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_PWDCABLE_PRES_MASK;

            /*Move to TYPEC_UNATTACHED_WAIT_SRC state if current state is TYPEC_ATTACHED_SRC.
              A PR_Swap/FR_Swap from Sink to Source should not be considered
              as a detach. So, don't do anything */
            if ((TYPEC_ATTACHED_SRC == u8TypeCState)
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                    && (u8TypeCSubState != TYPEC_ATTACHED_SRC_SWAP_RD_PRES_DETECT_SS)
#endif
               )
            {
                u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
            }
            else if (TYPEC_ATTACHWAIT_SRC == u8TypeCState)
            {
                /*Kill the TCC debounce timer running already*/
                TypeC_KillTypeCTimer(u8PortNum);

                /*Move to TYPEC_UNATTACHED_SRC state if current state is  TYPEC_ATTACHWAIT_SRC*/
                u8TypeCState = TYPEC_UNATTACHED_SRC;
                u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
            }
            else
            {
                /* Do Nothing */
            }
#endif
            break;
        }


        /*Only Sink Device is Present*/
        case TYPEC_UFP_ATT_DEF:
        case TYPEC_UFP_ATT_3A0:
        {
            DEBUG_PRINT_PORT_STR ((((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 1 : 2)<<16) | u8TypeCState, "TYPEC: Only Sink is Present in CC\r\n");

            if (TYPEC_UNATTACHED_SRC == u8TypeCState)
            {
                /*Setting the state for tCCDebounce*/
                u8TypeCState = TYPEC_ATTACHWAIT_SRC;
                u8TypeCSubState = TYPEC_ATTACHWAIT_SRC_ENTRY_SS;

                /*Clearing the Powered cable presence in u16PortSts variable*/
                gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;
            }
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
            else if ((TYPEC_ATTACHED_SRC == u8TypeCState) &&
                     (TYPEC_ATTACHED_SRC_SWAP_RD_PRES_DETECT_SS == u8TypeCSubState))
            {
                /* This condition would be hit during Sink to Source PR_Swap/FR_Swap */
                u8TypeCSubState = TYPEC_ATTACHED_SRC_DRIVE_PWR_SS;
                /*Clearing the Powered cable presence in u16PortSts variable*/
                gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;
            }
#endif
            /* After unplug typec cable, trigger detach if sw typec state is attached arc and hw fsm is attached sink */
            else if((TYPEC_ATTACHED_SRC == u8TypeCState) && 
                (Hv_Typec_RegReadByte(u8PortNum, 0x024c) != TYPEC_FSM_STATE_ATTACH_WAIT_SOURCE) &&
                (Hv_Typec_RegReadByte(u8PortNum, 0x024c) != TYPEC_FSM_STATE_ATTACHED_SOURCE))
            {
                DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: Plug out in attached src state but fsm state is not 8\r\n");

                u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
            }
            else
            {
                /* Do Nothing */
            }
            break;
        }

        /*Both Powered cable and sink is Present*/
        case (TYPEC_PWD_CABLE_ATT_DEF ^ TYPEC_UFP_ATT_DEF):
        case (TYPEC_PWD_CABLE_ATT_1A5 ^ TYPEC_UFP_ATT_1A5):
        case (TYPEC_PWD_CABLE_ATT_3A0 ^ TYPEC_UFP_ATT_3A0):
        {
            /*Setting the Powered cable presence in u8PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_PWDCABLE_PRES_MASK;

            DEBUG_PRINT_PORT_STR (u8TypeCState, "TYPEC: Sink is Present in CC");
            DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 2 : 1),
                                  "\r\n");

            DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: Powered Cable is Present in CC");
            DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 1 : 2),
                                  "\r\n");

            if (TYPEC_UNATTACHED_SRC == u8TypeCState)
            {
                /*Setting the state for tCCDebounce*/
                u8TypeCState = TYPEC_ATTACHWAIT_SRC;
                u8TypeCSubState = TYPEC_ATTACHWAIT_SRC_ENTRY_SS;
            }
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
            else if ((TYPEC_ATTACHED_SRC == u8TypeCState) &&
                     (TYPEC_ATTACHED_SRC_SWAP_RD_PRES_DETECT_SS == u8TypeCSubState))
            {
                u8TypeCSubState = TYPEC_ATTACHED_SRC_DRIVE_PWR_SS;
            }
#endif
            else
            {
                /* Do Nothing */
            }
            break;
        }


#if (HV_TYPEC_CONFIG_VCONN_ENABLE == HV_CONFIG_OFF)
        case TYPEC_CC1CC2_EQ:
        {
            /*No Devices are Present*/
            if (!gasTypeCcontrol[u8PortNum].u8CC1MatchISR)
            {
                /*Clearing the Powered cable presence in u8PortSts variable*/
                gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;

                DEBUG_PRINT_PORT_STR (u8TypeCState, "TYPEC: No Devices are present\r\n");

                if (TYPEC_ATTACHWAIT_SRC == u8TypeCState)
                {
                    /*Kill the TCC debounce timer running already*/
                    TypeC_KillTypeCTimer(u8PortNum);

                    /*Move to TYPEC_UNATTACHED_SRC state  if current state is
                    TYPEC_ATTACHWAIT_SRC*/
                    u8TypeCState = TYPEC_UNATTACHED_SRC;
                    u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
                }
                else if (TYPEC_ATTACHED_SRC == u8TypeCState)
                {
                    /*Move to TYPEC_UNATTACHED_WAIT_SRC state if current state is
                    TYPEC_ATTACHED_SRC. A FR_Swap from Sink to Source should
                    not be considered as a detach. So, don't do anything */
                    if (!((DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)) && \
                            (DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))))
                    {
                        u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                        u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
                    }
                }
                else
                {
                    /* Do Nothing */
                }
            }
            break;
        }
#else
        case TYPEC_CC1CC2_EQ:
        {
            /*Audio Adapter Accessory is Present*/
            if (gasTypeCcontrol[u8PortNum].u8CC1MatchISR == gasTypeCcontrol[u8PortNum].u8CCDebMatch)
            {
                #if (HV_TYPEC_CONFIG_TYPEC_MODE != TYPEC_MODE_SRC)
                /*Consider the CC Sample values as valid Audio accessory attach only at the
                unattached state*/
                /*This avoids unwanted transition in attached state*/
                if (TYPEC_UNATTACHED_SRC == u8TypeCState)
                {
                    DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: AUDIO ACCESSORY is present\r\n");

                    /*Setting the state for tCCDebounce*/
                    u8TypeCState = TYPEC_ATTACHWAIT_SRC;
                    u8TypeCSubState = TYPEC_ATTACHWAIT_SRC_ENTRY_SS;
                }
                else
                #endif
                {
                    if(TYPEC_ATTACHED_SRC == u8TypeCState)
                    {
                        DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: Plug out for u8CC1MatchISR == u8CC2MatchISR\r\n");

                        u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                        u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
                    }
                }
            }
            /*No Devices are Present*/
            else if (!gasTypeCcontrol[u8PortNum].u8CC1MatchISR)
            {
                /*Clearing the Powered cable presence in u8PortSts variable*/
                gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;

                DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: No Devices are present\r\n");

                if (TYPEC_ATTACHWAIT_SRC == u8TypeCState)
                {
                    /*Kill the TCC debounce timer running already*/
                    TypeC_KillTypeCTimer(u8PortNum);

                    /*Move to TYPEC_UNATTACHED_SRC state  if current state is
                    TYPEC_ATTACHWAIT_SRC*/
                    u8TypeCState = TYPEC_UNATTACHED_SRC;
                    u8TypeCSubState = TYPEC_UNATTACHED_SRC_ENTRY_SS;
                }
                else if (TYPEC_ATTACHED_SRC == u8TypeCState)
                {
                    /*Move to TYPEC_UNATTACHED_WAIT_SRC state if current state is
                    TYPEC_ATTACHED_SRC. A FR_Swap from Sink to Source should
                    not be considered as a detach. So, don't do anything */
                    if (!((DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum)) && \
                            (DPM_IS_FRS_XMT_OR_DET_ENABLED(u8PortNum))))
                    {
                        u8TypeCState = TYPEC_UNATTACHED_WAIT_SRC;
                        u8TypeCSubState = TYPEC_UNATTACHED_WAIT_SRC_ENTRY_SS;
                    }
                }
                else
                {
                    /* Do Nothing */
                }
            }
            /*Debug Accessory is Present*/
            else
            {
                /*Consider the CC Sample values as valid Debug accessory attach only at the
                unattached state*/
                /*This avoids unwanted transition in attached state*/
                if (TYPEC_UNATTACHED_SRC == u8TypeCState)
                {
                    DEBUG_PRINT_PORT_STR(u8PortNum, "TYPEC: DEBUG ACCESSORY is present\r\n");
                    /*Setting the state for tCCDebounce    */
                    u8TypeCState = TYPEC_ATTACHWAIT_SRC;
                    u8TypeCSubState = TYPEC_ATTACHWAIT_SRC_ENTRY_SS;
                }
            }
            break;
        }
#endif
        default:
            break;
    }
    gasTypeCcontrol[u8PortNum].u8TypeCState = u8TypeCState;
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = u8TypeCSubState;
}


VOID TypeC_UpdatePwdCableStatus (UINT8 u8PortNum)
{
    /*Assigning the structure variables to local variables to reduce the code size as
    accessing the structure members takes lot of code*/

    UINT8 u8TypeCState = gasTypeCcontrol[u8PortNum].u8TypeCState;
    UINT8 u8TypeCSubState = gasTypeCcontrol[u8PortNum].u8TypeCSubState;

    DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC: TypeC_UpdatePwdCableStatus\r\n");
    switch (gasTypeCcontrol[u8PortNum].u8CC1MatchISR ^ gasTypeCcontrol[u8PortNum].u8CC2MatchISR)
    {
        /*Only Powered Cable is present*/
        case TYPEC_PWD_CABLE_ATT_DEF:
        case TYPEC_PWD_CABLE_ATT_1A5:
        case TYPEC_PWD_CABLE_ATT_3A0:
        {
            DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC: Only Powered Cable is Present in CC\r\n");

            /*Setting the Powered cable presence in u8PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_PWDCABLE_PRES_MASK;

            break;
        }


        /*Only Sink Device is Present*/
        case TYPEC_UFP_ATT_DEF:
        case TYPEC_UFP_ATT_3A0:
        {
            DEBUG_PRINT_PORT_STR (u8PortNum<<16 | u8TypeCState,"TYPEC: Only Sink is Present in CC\r\n");

            /*Clearing the Powered cable presence in u16PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;
            break;
        }

        /*Both Powered cable and sink is Present*/
        case (TYPEC_PWD_CABLE_ATT_DEF ^ TYPEC_UFP_ATT_DEF):
        case (TYPEC_PWD_CABLE_ATT_1A5 ^ TYPEC_UFP_ATT_1A5):
        case (TYPEC_PWD_CABLE_ATT_3A0 ^ TYPEC_UFP_ATT_3A0):
        {
            /*Setting the Powered cable presence in u8PortSts variable*/
            gasTypeCcontrol[u8PortNum].u8PortSts |= TYPEC_PWDCABLE_PRES_MASK;

            DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC: Sink is Present in CC");
            DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 2 : 1),"\r\n");

            DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC: Powered Cable is Present in CC");
            DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 1 : 2),"\r\n");

            DEBUG_PRINT_PORT_STR (u8PortNum<<16 | u8TypeCState<<8 | u8TypeCSubState,"TYPEC: u8TypeCState u8TypeCSubState\r\n");

            break;
        }
        case TYPEC_CC1CC2_EQ:
        {
            /*No Devices are Present*/
            if (!gasTypeCcontrol[u8PortNum].u8CC1MatchISR)
            {
                /*Clearing the Powered cable presence in u8PortSts variable*/
                gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_PWDCABLE_PRES_MASK;

                DEBUG_PRINT_PORT_STR (u8PortNum,"TYPEC: No Devices are present\r\n");
            }
            break;
        }
        default:
        break;
    }
}
#endif /*INCLUDE_PD_SOURCE*/

#if (HV_TRUE == INCLUDE_PD_SINK)

void TypeC_SnkIntrHandler (UINT8 u8PortNum)
{
    /*Assigning the structure variables to local variables to reduce the code size as
    accessing the structure members takes lot of code*/
    UINT8 u8TypeCState = gasTypeCcontrol[u8PortNum].u8TypeCState;
    UINT8 u8TypeCSubState = gasTypeCcontrol[u8PortNum].u8TypeCSubState;

    DEBUG_PRINT_PORT_STR(gasTypeCcontrol[u8PortNum].u8CC1MatchISR<<8 | gasTypeCcontrol[u8PortNum].u8CC2MatchISR,"TypeC_SnkIntrHandler u8CCMatchISR\r\n");

    switch (gasTypeCcontrol[u8PortNum].u8CC1MatchISR ^ gasTypeCcontrol[u8PortNum].u8CC2MatchISR)
    {
        case TYPEC_DFP_DEF_ATT:
        case TYPEC_DFP_1A5_ATT:
        case TYPEC_DFP_3A0_ATT:
        case (TYPEC_DFP_DEF_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        case (TYPEC_DFP_1A5_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        case (TYPEC_DFP_3A0_ATT ^ TYPEC_SNK_CCTHRES_VCONN_ON):
        {
            /*Decode and store the Rp value of Source attached*/
            //DEBUG_PRINT_PORT_STR(u8PortNum,">>> TypeC_DecodeCCSourceRpValue called by TypeC_SnkIntrHandler\r\n");
            TypeC_DecodeCCSourceRpValue (u8PortNum);

            if (TYPEC_ATTACHWAIT_SNK == u8TypeCState)
            {
                /*Kill the TPD Debounce timer running for last detach event or
                Kill the TCC Debounce timer running for previous attach event*/
                TypeC_KillTypeCTimer(u8PortNum);
            }
            else if ((TYPEC_ATTACHED_SNK == u8TypeCState) && ((((UINT8)TYPEC_ATTACHED_SNK_RUN_SM_SS) == u8TypeCSubState)
#if (HV_TRUE == (INCLUDE_PD_PR_SWAP || INCLUDE_PD_FR_SWAP))
                     || (((UINT8)TYPEC_ATTACHED_SNK_SWAP_VBUS_PRES_DETECT_SS) == u8TypeCSubState)
#endif
                                                             ))
            {
                break;
            }
#if(HV_TRUE == INCLUDE_PD_FR_SWAP)
            else if ((TYPEC_ATTACHED_SNK == u8TypeCState) && (TYPEC_ATTACHED_SNK_SWAP_ATTACH_DETECT_SS == u8TypeCSubState))
            {
                u8TypeCState = TYPEC_ATTACHED_SNK;
                u8TypeCSubState = TYPEC_ATTACHED_SNK_ENTRY_SS;
                break;
            }
#endif
            else
            {
                /*Attach event has occurred within the TPD Debounce timeout of previous Detach event
                So in this case moving to the Attach wait state and also killing the
                TPD Debounce timer which is active currently*/
                if ((TYPEC_ATTACHED_SNK == u8TypeCState) && (u8TypeCSubState != ((UINT8)TYPEC_ATTACHED_SNK_RUN_SM_SS)))
                {
                    /*Kill the TPD Debounce timer running previously for detach event*/
                    TypeC_KillTypeCTimer (u8PortNum);
                }

                DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: Source is Present in CC");
                DEBUG_PRINT_PORT_STR (((gasTypeCcontrol[u8PortNum].u8CC1MatchISR > gasTypeCcontrol[u8PortNum].u8CC2MatchISR) ? 1 : 2),
                                      "\r\n");
            }

            /*Disable the Protocol layer receiver function since moving to Attach wait state*/
            PRL_EnableRx (u8PortNum, HV_FALSE);

            /*Setting the state as TYPEC_ATTACHWAIT_SNK for Tcc Debounce and VBUS presence
            check*/
            u8TypeCState = TYPEC_ATTACHWAIT_SNK;
            u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_ENTRY_SS;
            break;
        }

        case TYPEC_NO_THRESHOLD:
        {
            /*Valid Detach event happens only when both the CC1 and CC2 are 0*/
            if (SET_TO_ZERO == gasTypeCcontrol[u8PortNum].u8CC1MatchISR)
            {
                DEBUG_PRINT_PORT_STR (u8TypeCState, "TYPEC: NO DEVICES ARE PRESENT\r\n");

                if (TYPEC_ATTACHWAIT_SNK == u8TypeCState)
                {
                    /*Kill the TCC Debounce timer running previously attach event*/
                    TypeC_KillTypeCTimer (u8PortNum);
                    u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_START_PD_DEB_SS;
                }
                /*Source detach occurs before the VBUS drops below VSinkdisconnect */
                else if ((TYPEC_ATTACHED_SNK == u8TypeCState) && \
                         (TYPEC_ATTACHED_SNK_RUN_SM_SS == u8TypeCSubState))
                {
                    /*During Sink to Source PR_Swap/FR_Swap, this condition would be hit when PS_RDY
                      is not received and PSSourceOf timer expires. At that point, both the partners
                      might have Rd in CC wire. As a result of which, CC debounce thresholds
                      will not match. This condition shall not be treated as a detach */
                    if (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum))
                    {
                        /* Go to TYPEC_ATTACHED_SNK_START_PD_DEB_SS sub-state for starting tPDDebounce */
                        u8TypeCSubState = TYPEC_ATTACHED_SNK_START_PD_DEB_SS;
                    }
                }
                /* This condition occurs if VCONN Discharge is enabled in
                   Attached Sink State or Source detach occurs after VBUS drops
                   below VSinkdisconnect. A PR_Swap/FR_Swap from Source to Sink should
                   not be considered as a detach. So, don't do anything */
                else if ((TYPEC_ATTACHED_SNK == u8TypeCState)
#if (HV_TRUE == INCLUDE_PD_PR_SWAP)
                         && (u8TypeCSubState != TYPEC_ATTACHED_SNK_SWAP_VBUS_PRES_DETECT_SS)
#endif
#if (HV_TRUE == INCLUDE_PD_FR_SWAP)
                         && (u8TypeCSubState != TYPEC_ATTACHED_SNK_SWAP_ATTACH_DETECT_SS)
                         && (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum))
#endif
                        )
                {
                    u8TypeCState = TYPEC_UNATTACHED_SNK;
                    u8TypeCSubState = TYPEC_UNATTACHED_SNK_ENTRY_SS;
                }
                else
                {
                    /* Do Nothing */
                }
            }
            break;
        }

        case TYPEC_SNK_CCTHRES_VCONN_ON:
        {
            /* This condition occurs during a detach when the power role of the
               port is Sink and VCONN role is Source */
            if ((TYPEC_ATTACHED_SNK == u8TypeCState) && \
                    (TYPEC_ATTACHED_SNK_RUN_SM_SS == u8TypeCSubState))
            {
                if (HV_FALSE == DPM_IS_PR_OR_FR_SWAP_IN_PROGRESS(u8PortNum))
                {
                    /* Go to TYPEC_ATTACHED_SNK_START_PD_DEB_SS sub-state for starting tPDDebounce */
                    u8TypeCSubState = TYPEC_ATTACHED_SNK_START_PD_DEB_SS;
                }
            }
            else if ((TYPEC_UNATTACHED_SNK == u8TypeCState) || (TYPEC_ATTACHWAIT_SNK == u8TypeCState))
            {
                /*This threshold will get hit when DFP Connected and advertising
                proprietary current. Setting the state as TYPEC_ATTACHWAIT_SNK
                for Tcc Debounce and VBUS presence check*/

                TypeC_KillTypeCTimer (u8PortNum);

                /*Disable the Protocol layer receiver function since moving to Attach wait state*/
                PRL_EnableRx (u8PortNum, HV_FALSE);

                u8TypeCState = TYPEC_ATTACHWAIT_SNK;
                u8TypeCSubState = TYPEC_ATTACHWAIT_SNK_ENTRY_SS;
            }
            else
            {
                /*Execution is not expected to hit here.
                 Do nothing.*/
            }
            break;
        }

        case (TYPEC_DFP_ACT_3A0 | TYPEC_DFP_UFP_3A0):
        {
            if((PD_ROLE_DRP == DPM_GET_DEFAULT_POWER_ROLE(u8PortNum)) && (TYPEC_UNATTACHED_SNK == u8TypeCState))
            {
                HV_LOG_INFO(TYPEC,"Toggle Typec");
                // Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
                // Hv_Vos_MSleep(200);
                // Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TYPEC_RST, UPD_TYPEC_PD_RST_RSTN_CCDET);
            }
        }

        default:
            break;
    }

    
    /*Clearing the Hard Reset IN Progress bit here because source detach
    can occur while waiting in ePE_SNK_TRANSITION_TO_DEFAULT_WAIT_SS*/
    if (u8TypeCState == TYPEC_UNATTACHED_SNK)
    {
        DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: TYPEC_UNATTACHED_SNK in CC INTR\r\n");
        gasPolicyEngine[u8PortNum].u8PEPortSts &= ~PE_HARDRESET_PROGRESS_MASK;
    }

    gasTypeCcontrol[u8PortNum].u8TypeCState = u8TypeCState;
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = u8TypeCSubState;
}
#endif
/*INCLUDE_PD_SINK*/

void TypeC_OnVCONNDISCHComplete (UINT8 u8PortNum)
{
    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC: VCONN_DISCH COMPLETE\r\n");

    HV_PSF_HOOK_VCONN_CC1_DISCHARGE_SET(u8PortNum, HV_FALSE);
    HV_PSF_HOOK_VCONN_CC2_DISCHARGE_SET(u8PortNum, HV_FALSE);

#if (HV_TRUE == INCLUDE_PD_SOURCE)
    if (PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        /*Setting the user given Rp value for source since it is changed to open disconnect
        while VCONN Discharge*/
        TypeC_SetCCDefaultRpValue (u8PortNum);
    }
#endif

#if (HV_TRUE == INCLUDE_PD_SINK)
    if (PD_ROLE_SINK == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        TypeC_SetCCDebounceVariable (u8PortNum, TYPEC_UFP);

        /*Reset only the Rd value for the CC pin in which VCONN was sourced*/
        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SINK, TYPEC_ROLE_SINK_RD, TYPEC_ENABLE_CC1_CC2);

        /*Resetting the CC Debounce clear enable,CC Match Enable,CC Sample Enable register*/
        TypeC_SetCCSampleEnable (u8PortNum, TYPEC_ENABLE_CC1_CC2);
    }
#endif

    Hv_Typec_RegByteSetBit (u8PortNum, UPD_REG_RW_CC_VCONN_SEL, UPD_VCONN_CC1_SEL);                //1: CC1, 0: VCONN
    Hv_Typec_RegByteSetBit (u8PortNum, UPD_REG_RW_CC_VCONN_SEL, UPD_VCONN_CC2_SEL);                //1: CC2, 0: VCONN

    UINT32 u32Cnt = 0;
    while (u32Cnt++ < 5000)
    {
        /* delay，原因怀疑是VCONN掉电太慢 */
    }

    /* 实测中发现， 在hard reset期间， vconn off后没有触发cc中断， 所以u8CC1MatchISR、u8CC2MatchISR没有更新， 从而导致
       再次打开vconn的时候，cc1还是cc2做vconn port出现错误.
       workaround: 在vconn off complete后再次读取cc adc进行判断 */
    TypeC_CCDetHandleFunc(u8PortNum);
}

/*******************************************************************************************/
/*********************************TypeC Collision avoidance Support APIs**************************************/
/*******************************************************************************************/
/*Change the Rp Value only for the CC pin in which source is connected*/
void TypeC_SetRpCollAvoidance (UINT8 u8PortNum, UINT8 u8RpValue)
{
    UINT8 u8CCEnablePin, u8CCCompCtrl;

    /* Setting the CC Comparator OFF */
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

    /* Clearing the Rp value in u8PortSts */
    gasTypeCcontrol[u8PortNum].u8PortSts &= ~TYPEC_CURR_RPVAL_MASK;

    /*Rp value as 1.5A@5V */
    if (TYPEC_SINK_TXNG == u8RpValue)
    {
        gasTypeCcontrol[u8PortNum].u8CCDebMatch = (TYPEC_CC_THRES1_MATCH | TYPEC_CC_THRES5_MATCH);
        gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch = (TYPEC_CC_THRES5_MATCH);

        /*Setting the current Rp value as TYPEC_RP_CURRENT_15 in u8PortSts variable*/
        gasTypeCcontrol[u8PortNum].u8PortSts |= (TYPEC_RP_CURRENT_15 << TYPEC_CURR_RPVAL_POS);

        //Hv_Typec_RegByteClearBit(u8PortNum, UPD_REG_RW_TX_MSG_CONTROL, (BIT(0) | BIT(2)));   //disable auto response goodcrc

        /*Setting the Rp Value as SinkTxNG*/
        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, TYPEC_ROLE_SOURCE_15, TYPEC_ENABLE_CC1_CC2);

        DEBUG_PRINT_PORT_STR (u8PortNum, "TypeC-CA: Rp set to SinkTxNG\r\n");
    }
    /*Rp value as 3.0A@5V */
    else
    {
        gasTypeCcontrol[u8PortNum].u8CCDebMatch = (TYPEC_CC_THRES3_MATCH | TYPEC_CC_THRES6_MATCH);
        gasTypeCcontrol[u8PortNum].u8CCSrcSnkMatch = (TYPEC_CC_THRES6_MATCH);

        /*Setting the current Rp value as TYPEC_RP_CURRENT_30 in u8PortSts variable*/
        gasTypeCcontrol[u8PortNum].u8PortSts |= (TYPEC_RP_CURRENT_30 << TYPEC_CURR_RPVAL_POS);

        //Hv_Typec_RegByteSetBit(u8PortNum, UPD_REG_RW_TX_MSG_CONTROL, (BIT(0) | BIT(2)));        //auto response goodcrc

        /*Setting the Rp Value as SinkTxOk*/
        TypeC_SetCCPowerRole (u8PortNum, TYPEC_ROLE_SOURCE, TYPEC_ROLE_SOURCE_30, TYPEC_ENABLE_CC1_CC2);

        DEBUG_PRINT_PORT_STR (u8PortNum, "TypeC-CA: Rp set to SinkTxOK\r\n");
    }

    /*Enabling the CC Sampling in the sink attached CC pin if both sink and powered cable
    are attached*/
    /*Sink Attached in CC1 since VCONN is enabled in CC2*/
    if (TYPEC_VCONN_SOURCE_CC2 == (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
    {
        u8CCEnablePin = TYPEC_ENABLE_CC1;
        u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC1;
    }
    /*Sink Attached in CC2 since VCONN is enabled in CC1*/
    else if (TYPEC_VCONN_SOURCE_CC1 == (gasTypeCcontrol[u8PortNum].u8IntStsISR & TYPEC_VCONN_SOURCE_MASK))
    {
        u8CCEnablePin = TYPEC_ENABLE_CC2;
        u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC2;
    }
    /*Enabling the CC Sampling in both the CC pins if only sink is attached*/
    else
    {
        u8CCEnablePin = TYPEC_ENABLE_CC1_CC2;
        u8CCCompCtrl = TYPEC_CC_COMP_CTL_CC1_CC2;
    }

    UINT32 u32Cnt = 0;
    while (u32Cnt++ < 10000)
    {
        //delay, 设置TX NG/OK时，会触发CC中断问题，导致软件状态机错误，怀疑CC修改后电平变化缓慢
    }

    /* Changing the CC Sampling value as per the Rp value set */
    TypeC_SetCCSampleEnable (u8PortNum, u8CCEnablePin);

    /* Setting the CC Comparator ON */
    TypeC_ConfigCCComp (u8PortNum, u8CCCompCtrl);
}

/*******************************************************************************************/
/*********************************TypeC VBUS Comparator Support Functions**************************************/
/*******************************************************************************************/
void TypeC_SetVBUSCompONOFF (UINT8 u8PortNum, UINT8 u8ConfigVal)
{
    //no VBUS detect intr to use, then use the polling method
    gasTypeCcontrol[u8PortNum].u8Typec_VbusCompSta = u8ConfigVal;

    /* read the vbus imidiately when vbus comp on */
    if (u8ConfigVal)
    {
        u16VbusINAPre[u8PortNum] = TYPEC_VBUS_THR_VAL_INIT;
    }
}
/**************************************************************/
void TypeC_ConfigureVBUSThr(UINT8 u8PortNum, UINT16 u16Voltage, UINT16 u16Current, UINT8 u8PowerFaultThrConfig) {
#if 0
    UINT16 u16MinVoltageThr = 0;
    UINT16 u16MaxVoltageThr = 0;
    UINT8 u8SampleEn = 0;

    // 设置 VBUS 比较器为关闭状态
    TypeC_SetVBUSCompONOFF(u8PortNum, TYPEC_VBUSCOMP_OFF);

    // 根据目标电压配置阈值
    switch (u16Voltage) {
        case TYPEC_VBUS_0V:
            // 配置 VSafe0V 阈值
            u8SampleEn = TYPEC_VSAFE0V_MAX_THR_MATCH;
            break;

        case TYPEC_VBUS_5V:
            // 配置 VSafe5V 的最小和最大阈值
            u16MinVoltageThr = ROUND_OFF_FLOAT_TO_INT(TYPEC_DESIRED_MIN_SNK_VSAFE5V_VBUS_THR);
            u16MaxVoltageThr = ROUND_OFF_FLOAT_TO_INT(TYPEC_DESIRED_MAX_SNK_VSAFE5V_VBUS_THR);
            u8SampleEn = TYPEC_DESIRED_MIN_V_THR1_MATCH | TYPEC_PREV_V_DROP_CHK_THR4_MATCH;
            break;

        default:
            // 配置其他电压的最小和最大阈值
            u16MinVoltageThr = ROUND_OFF_FLOAT_TO_INT(TYPEC_GET_DESIRED_MIN_VBUS_THR(u16Voltage));
            u16MaxVoltageThr = ROUND_OFF_FLOAT_TO_INT(TYPEC_GET_DESIRED_MAX_VBUS_THR(u16Voltage));
            u8SampleEn = TYPEC_DESIRED_MIN_V_THR1_MATCH | TYPEC_PREV_V_DROP_CHK_THR4_MATCH;
            break;
    }

    // 如果目标电压不是 0V，则设置阈值
    if (u16Voltage != TYPEC_VBUS_0V) {
        u16aVBUSThrVal[2] = u16MinVoltageThr; // 设置最小阈值
        u16aVBUSThrVal[5] = u16MaxVoltageThr; // 设置最大阈值
    }

    // 启用 VBUS 采样
    gasTypeCcontrol[u8PortNum].u8VbusDebMatch = u8SampleEn;
#endif
    // 启用 VBUS 比较器
    TypeC_SetVBUSCompONOFF(u8PortNum, TYPEC_VBUSCOMP_ON);
}

/************************************************************************/
/*******************************************************************************************/
/*********************************TypeC Timer CB**************************************/
/*******************************************************************************************/
void TypeC_SubStateChange_TimerCB (UINT8 u8PortNum, UINT8 u8TypeCSubState)
{
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = u8TypeCSubState;
    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = MAX_CONCURRENT_TIMERS;
}

void TypeC_StateChange_TimerCB (UINT8 u8PortNum, UINT8 u8TypeCState)
{
    gasTypeCcontrol[u8PortNum].u8TypeCState = u8TypeCState;
    gasTypeCcontrol[u8PortNum].u8TypeCSubState = SET_TO_ZERO;
    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = MAX_CONCURRENT_TIMERS;
}

void TypeC_KillTypeCTimer (UINT8 u8PortNum)
{
    PDTimer_Kill (gasTypeCcontrol[u8PortNum].u8TypeCTimerID);

    /*Setting the u8PETimerID to MAX_CONCURRENT_TIMERS to indicate that
    TimerID does not hold any valid timer IDs anymore*/
    gasTypeCcontrol[u8PortNum].u8TypeCTimerID = MAX_CONCURRENT_TIMERS;
}

/*******************************************************************************************/
/*********************************TypeC Common Support APIs**************************************/
/*******************************************************************************************/
UINT16 TypeC_ObtainCurrentValueFrmRp (UINT8 u8PortNum)
{
    UINT16 u16ReturnVal;
    UINT8 u8RpVal = ((gasTypeCcontrol[u8PortNum].u8PortSts & TYPEC_CURR_RPVAL_MASK) >> TYPEC_CURR_RPVAL_POS);

    switch (u8RpVal)
    {
        case TYPEC_DFP_DEFAULT_CURRENT:
        {
            u16ReturnVal = DPM_900mA;
            break;
        }
        case TYPEC_DFP_1A5_CURRENT:
        {
            u16ReturnVal = DPM_1500mA;
            break;
        }
        case TYPEC_DFP_3A0_CURRENT:
        {
            u16ReturnVal = DPM_3000mA;
            break;
        }
        default:
        {
            u16ReturnVal = DPM_0mA;
            break;
        }
    }

#if (HV_TRUE == INCLUDE_PD_SINK)
    /* Set the Sink Rp val status in u32PortConnectStatus */
    if (PD_ROLE_SINK == DPM_GET_CURRENT_POWER_ROLE(u8PortNum))
    {
        gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus &= \
                ~DPM_PORT_RP_VAL_DETECT_MASK_STATUS;
        gasCfgStatusData.sPerPortData[u8PortNum].u32PortConnectStatus |= \
                (u8RpVal << DPM_PORT_RP_VAL_DETECT_STATUS_POS);
    }
#endif

    return u16ReturnVal;
}

/*******************************************************************************************/
/**************************TypeC FRS Support Functions**************************************/
/*******************************************************************************************/
#if (HV_TRUE == INCLUDE_PD_FR_SWAP)

void TypeC_ConfigureFRSSignalDET (UINT8 u8PortNum)
{
    /* Ensure at minimum that pwr_sw_clk_gate_en, cable_plug_clk_gate_en, pd_mac_clk_gate_en,
       pio_clk_gate_en, and i2c_clk_gate_en (or spi_clk_gate_en) are cleared in Clock Gate Register */
    Hv_Typec_RegByteClearBit (u8PortNum, UPD_CLK_GATE_LOW, (UINT8)(UPD_PWR_SW_CLK_GATE_EN | \
                         UPD_I2C_CLK_GATE_EN | UPD_SPI_CLK_GATE_EN | UPD_PIO_CLK_GATE_EN));
    Hv_Typec_RegByteClearBit (u8PortNum, UPD_CLK_GATE_HIGH, (UINT8)(UPD_PD_MAC_CLK_GATE_EN | \
                         UPD_CABLE_PLUG_CLK_GATE_EN));

    /* Program the CC Comparator Control to 00b and disable the CC debouncer */
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

    /* Disable the VBUS debouncer */
    TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

    /* Program FRS CC Debounce Register with FRS CC debounce time of 30us */
    Hv_Typec_RegWriteByte (u8PortNum, TYPEC_FRS_CC_DEB, TYPEC_FRS_CC_DEB_30US);

    /* Program FRS Threshold Select Register with its default value to point to the FRSWAP threshold */
    Hv_Typec_RegWriteByte (u8PortNum, TYPEC_FRS_THR_SEL, TYPEC_FRS_THRESHOLD);

    /* Enable the UPD350 high level Extended interrupt*/
    UINT16 u16Data = Hv_Typec_RegReadWord (u8PortNum, UPDINTR_INT_EN);
    u16Data |= UPDINTR_EXT_INT;
    Hv_Typec_RegWriteWord (u8PortNum, UPDINTR_INT_EN, u16Data);

    /* Enable FRS_RCV_STS interrupt in Extended Interrupt Enable Register */
    Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_EXT_INT_EN, (UINT8)TYPEC_FRS_RCV_STS);

    /* Program FRS_VBUS_DEB register with FRS VBUS debounce time of 30us */
    Hv_Typec_RegWriteByte (u8PortNum, TYPEC_FRS_VBUS_DEB, TYPEC_FRS_VBUS_DEB_30US);

    /* Set CC High Bandwidth Mode Enable in CC Hardware Control Register */
    Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_CC_HW_CTL_LOW, (UINT8)TYPEC_CC_DET_HBW_EN);

    /* Program CC Sample Clock Register to enable >= 250KHz sampling rate */
    Hv_Typec_RegWriteByte (u8PortNum, UPD_CC_SAMP_CLK, \
                      (UINT8)(UPD_CC_SAMP_GEN_250_KS | UPD_CC_CLK_48_KHZ));

    /* Set VBUS High Bandwidth Mode Enable in VBUS Control 1 Register */
    Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_VBUS_CTL1_HIGH, (UINT8)TYPEC_VBUS_DET_HBW_EN);

    /* Program VBUS Sample Clock Register to enable >= 250KHz sampling rate */
    Hv_Typec_RegWriteByte (u8PortNum, UPD_VBUS_SAMP_CLK, \
                      (UINT8)(UPD_VBUS_SAMP_GEN_250_KS | UPD_VBUS_CLK_48_KHZ));

    /* Enable the VBUS debouncer */
    TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_ON);

    /* Program the CC Comparator Control in CC Control 1 Register to enable detection on the
       connected CC pin.*/
    TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);

    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC:FRS Signal Detection Enabled\r\n");
}

void TypeC_ConfigureFRSSignalXMT (UINT8 u8PortNum)
{
    /* Get the polarity of EN_FRS PIO */
    UINT8 u8EN_FRSPol = gasCfgStatusData.sPerPortData[u8PortNum].u8Mode_EN_FRS;

    /* Ensure at minimum that cable_plug_clk_gate_en, pd_mac_clk_gate_en,
       pio_clk_gate_en, and i2c_clk_gate_en (or spi_clk_gate_en) are cleared in Clock Gate Register */
    Hv_Typec_RegByteClearBit (u8PortNum, UPD_CLK_GATE_LOW, \
                         (UINT8)(UPD_I2C_CLK_GATE_EN | UPD_SPI_CLK_GATE_EN | UPD_PIO_CLK_GATE_EN));
    Hv_Typec_RegByteClearBit (u8PortNum, UPD_CLK_GATE_HIGH, \
                         (UINT8)(UPD_PD_MAC_CLK_GATE_EN | UPD_CABLE_PLUG_CLK_GATE_EN));

    /* Program FRS Transmission Length register with a value of 90us */
    Hv_Typec_RegWriteByte (u8PortNum, TYPEC_FRS_TX_LEN, TYPEC_FRS_TX_LEN_90US);

    /* Program the CC pin which has sink attached in FRS_CC_SEL in FRS Control Register */
    /* 5:4  Description
       00b: CC1 pin
       01b: CC2 pin
       1xb: CC1 and CC2 pin */
    /* In case of CC1 attach, clear both the bits */
    Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_FRS_CTL_LOW, (UINT8)TYPEC_FRS_CC_SEL);

    if (TYPEC_ORIENTATION_CC2 == TYPEC_GET_CC_ORIENTATION_STS(u8PortNum))
    {
        /* In case of CC2 attach, set Bit 4 */
        Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_FRS_CTL_LOW, (UINT8)TYPEC_FRS_CC_SEL_CC2);
    }

    /* Enable the UPD350 high level Extended interrupt*/
    UINT16 u16Data = Hv_Typec_RegReadWord (u8PortNum, UPDINTR_INT_EN);
    u16Data |= UPDINTR_EXT_INT;
    Hv_Typec_RegWriteWord (u8PortNum, UPDINTR_INT_EN, u16Data);

    /* Enable FRS_XMT_STS interrupt in Extended Interrupt Enable Register */
    Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_EXT_INT_EN, (UINT8)TYPEC_FRS_XMT_STS);

    /* PIO which is used to transmit FRS signal is indicated by programming FRS Request PIO Select Register*/
    Hv_Typec_RegWriteByte (u8PortNum, TYPEC_FRS_PIO_SEL, \
                      (gasCfgStatusData.sPerPortData[u8PortNum].u8Pio_EN_FRS << TYPEC_FRS_REQ_PIO_SEL_POS));

    /* Set PIO value that initiates transmission of FRS signaling
       based on the polarity of u8Pio_EN_FRS */
    if (((UINT8)eINPUT_ACTIVE_LOW == u8EN_FRSPol) || ((UINT8)eINPUT_ACTIVE_LOW_PU == u8EN_FRSPol))
    {
        Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_REQ_VAL);
    }
    else if (((UINT8)eINPUT_ACTIVE_HIGH == u8EN_FRSPol) || ((UINT8)eINPUT_ACTIVE_HIGH_PD == u8EN_FRSPol))
    {
        Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_REQ_VAL);
    }
    else
    {
        /* Do Nothing */
    }

    DEBUG_PRINT_PORT_STR (u8PortNum, "TYPEC:FRS Signal Transmission Enabled\r\n");
}

void TypeC_EnableFRSXMTOrDET (UINT8 u8PortNum, UINT8 u8IsFRSSupported)
{
    UINT8 u8IsSourcePort = ((PD_ROLE_SOURCE == DPM_GET_CURRENT_POWER_ROLE(u8PortNum)) ? HV_TRUE : HV_FALSE);

    if (u8IsFRSSupported)
    {
        /* Enable non-Power fault thresholds for TYPEC_VBUS_5V */
        /* Note: Here, TypeC_ConfigureVBUSThr() API is not used for setting the
           vSafe5V thresholds. This is done intentionally because calling that API
           with Non Pwr Fault Threshold argument will disable the Power fault detection
           and hence, we may fail to detect an actual OV/UV fault that
           could occur while waiting for an FRS event */
        /* Update the u16ExpectedVBUSVoltageInmV so that gasTypeCcontrol[u8PortNum].u8IntStsISR
           will be updated with correct VBUS Presence Mask value */
        gasDPM[u8PortNum].u16ExpectedVBUSVoltageInmV = TYPEC_VBUS_5V;

        /* Clear the VBUS Presence mask bits before configuring the VBUS threshold */
        HV_PSF_HOOK_DISABLE_GLOBAL_INTERRUPT();
        gasTypeCcontrol[u8PortNum].u8IntStsISR &= ~TYPEC_VBUS_PRESENCE_MASK;
        HV_PSF_HOOK_ENABLE_GLOBAL_INTERRUPT();

        /* Turn off the VBUS Comparator */
        TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_OFF);

        /* Disable Under Voltage for Source role only. Power loss is expected
           during an FRS. It shall not be treated as an under-voltage */
        if (u8IsSourcePort)
        {
            Hv_Typec_RegByteClearBit (u8PortNum, UPD_PIO_OVR_EN, UPD_PIO_OVR_1);
        }

        /* Configure vSafe5v(min) threshold */
        Hv_Typec_RegWriteWord (u8PortNum, TYPEC_VBUS_THR1, \
                          ROUND_OFF_FLOAT_TO_INT(((float)TYPEC_DESIRED_MIN_SRC_VSAFE5V_VBUS_THR *
                                  gasTypeCcontrol[u8PortNum].fVBUSCorrectionFactor)));

        /* Configure vSafe5v(max) threshold */
        Hv_Typec_RegWriteWord (u8PortNum, TYPEC_VBUS_THR4, \
                          ROUND_OFF_FLOAT_TO_INT(((float)TYPEC_DESIRED_MAX_SRC_VSAFE5V_VBUS_THR *
                                  gasTypeCcontrol[u8PortNum].fVBUSCorrectionFactor)));

        /* Configure the corresponding VBUS sample enable */
        UINT8 u8SampleEn = Hv_Typec_RegReadByte (u8PortNum, TYPEC_VBUS_SAMP_EN);
        if (u8IsSourcePort)
        {
            u8SampleEn &= ~(TYPEC_UNDER_VOLT_THR3_MATCH);
        }
        u8SampleEn |= (TYPEC_DESIRED_MIN_V_THR1_MATCH | TYPEC_PREV_V_DROP_CHK_THR4_MATCH);
        Hv_Typec_RegWriteByte (u8PortNum, TYPEC_VBUS_SAMP_EN, u8SampleEn);

        /* Turn on the VBUS Comparator */
        TypeC_SetVBUSCompONOFF (u8PortNum, TYPEC_VBUSCOMP_ON);

        if (u8IsSourcePort)
        {
            /* Configure UPD350 for FRS Signal Transmission */
            TypeC_ConfigureFRSSignalXMT (u8PortNum);

            /* Enable PIO Override */
            Hv_Typec_RegByteSetBit (u8PortNum, UPD_PIO_OVR_EN, (UINT8)UPD_PIO_OVR_3);

            /* Enable FRS_REQ_PIO bit in FRS_CTL register */
            Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_REQ_PIO);

            DEBUG_PRINT_PORT_STR(u8PortNum, "FRS XMT Enabled\r\n");
        }
        else /* PD_ROLE_SINK */
        {
            /* Configure UPD350 for FRS Signal Detection */
            TypeC_ConfigureFRSSignalDET (u8PortNum);

            /* Configure PIO Override Source
               When initial VBUS (at new source) < vSafe5V (min),
               New Source may turn on after detecting Fast Role Swap signal
               When initial VBUS (at new source) > vSafe5V (min),
               New Source may turn on at any time after VBUS falls below vSafe5V (max) */
            if (gasCfgStatusData.sPerPortData[u8PortNum].u16NegoVoltageInmV > TYPEC_VBUS_5V)
            {
                Hv_Typec_RegWriteByte (u8PortNum, UPD_PIO_OVR3_SRC_SEL,
                                  (UPD_PIO_OVR_SRC_SEL_VBUS_THR_AND_FRS_DET | UPD_PIO_OVR_VBUS4_THR_MATCH));
            }
            else
            {
                Hv_Typec_RegWriteByte (u8PortNum, UPD_PIO_OVR3_SRC_SEL, UPD_PIO_OVR_SRC_SEL_FRS_SIG_DETECTED);
            }

            /* Enable PIO Override */
            Hv_Typec_RegByteSetBit (u8PortNum, UPD_PIO_OVR_EN, (UINT8)UPD_PIO_OVR_3);

            /* Enable DC/DC pin function */
            PWRCTRL_ConfigDCDCEn (u8PortNum, HV_TRUE);

            /* Enable FRS Signal Detection */
            Hv_Typec_RegByteSetBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_DET_EN);

            DEBUG_PRINT_PORT_STR(u8PortNum, "FRS DET Enabled\r\n");
        }
        /* Set FRS XMT or DET Enabled status */
        DPM_ENABLE_FRS_XMT_OT_DET(u8PortNum);
    }
    else  /* FRS Criteria Not Supported for the port */
    {
        /* Disable FRS signal transmission and detection */
        if (u8IsSourcePort)
        {
            Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_REQ_PIO);

            DEBUG_PRINT_PORT_STR(u8PortNum, "FRS XMT Disabled\r\n");
        }
        else /* PD_ROLE_SINK */
        {
            Hv_Typec_RegByteClearBit (u8PortNum, TYPEC_FRS_CTL_HIGH, (UINT8)TYPEC_FRS_DET_EN);

            /* Disable DC/DC pin function */
            PWRCTRL_ConfigDCDCEn (u8PortNum, HV_FALSE);

            DEBUG_PRINT_PORT_STR(u8PortNum, "FRS DET Disabled\r\n");
        }

        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);

        /*Set the CC_SAMP_CLK bit as 0. Sampling period will be 100us*/
        Hv_Typec_RegWriteByte (u8PortNum, UPD_CC_SAMP_CLK, \
                          (UINT8) (UPD_CC_SAMP_GEN_10_KS | UPD_CC_CLK_20_KHZ));

        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_CC1_CC2);

        /* Disable PIO Override since FRS XMT/DET is disabled */
        Hv_Typec_RegByteClearBit (u8PortNum, UPD_PIO_OVR_EN, (UINT8)UPD_PIO_OVR_3);

        /* Clear FRS XMT or DET Enabled status */
        DPM_DISABLE_FRS_XMT_OR_DET(u8PortNum);
    }
}

#endif /* INCLUDE_PD_FR_SWAP */


void Hv_Drv_Typec_SwCtrlRpRd(UCHAR8 u8PortNum, UCHAR8 u8Open)
{
    if (u8Open == 0)
    {
        TypeC_DRPEnDisToggle(u8PortNum, HV_FALSE);
        TypeC_ConfigCCComp (u8PortNum, TYPEC_CC_COMP_CTL_DIS);
        if (u8PortNum == 0)
        {
            HV_LOG_INFO(TYPEC,"Hv_Drv_Typec_SwCtrlRpRd 0 0 ");

            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_sw_ctrl_rd_en, 1);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_sw_ctrl_rp_en, 1);
            /* Simulate Typec Unplug*/
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_cc1_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_cc2_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_cc1_rp_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_cc2_rp_en, 0);
        }
        else
        {
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_sw_ctrl_rd_en, 1);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_sw_ctrl_rp_en, 1);
            /* Simulate Typec Unplug*/
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_cc1_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_cc2_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_cc1_rp_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_cc2_rp_en, 0);
        }
    }
    else
    {
        if (u8PortNum == 0)
        {
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_sw_ctrl_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_00_04, 0x00, reg_00_sw_ctrl_rp_en, 0);
        }
        else
        {
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_sw_ctrl_rd_en, 0);
            HV_W32_FIELD_EX(STANDBY_USB_TYPEC_TOP_01_04, 0x00, reg_01_sw_ctrl_rp_en, 0);
        }

            HV_LOG_INFO(TYPEC,"Hv_Drv_Typec_SwCtrlRpRd 0 1 ");
    }
}
