Skip navigation
Home > All Places > USB > EZ-PD Type-C USB > Blog > 2018 > June > 21

CCG3 SDK notebook firmware example project is Dual Role Power (Power source and Power sink) and support Data source (DisplayPort source or USB3.x data host). It is regards as hardware of CY4531 board.

a. SDK firmware download link:http://www.cypress.com/documentation/software-and-drivers/ez-pd-software-development-kit?source=search&cat=software_tool…

b. CY4531 download link: http://www.cypress.com/documentation/development-kitsboards/cy4531-ez-pd-ccg3-evaluation-kit

 

CCG3 have Integrated Hardware based over-current protection (OCP), related pin is pin#39 OC Over-current Sensor Input. The standard circuits recommended to realize OCP can be refer below (highlight with red box).

 

You are correct that this is only on Provider path. Which meant the firmware is following the hardware design, the OCP only on Power source role. If you are designing a power sink with CCG3 and could like to implement OCP on consumer path. This is the right place to take a look.

 

Copy functions with power source role and update OCP features in sink role. (The OCP on power source role is disabled, since this is UFP target.)

Hardware end, you need Rsense 10mOhm on power consumer path same as above. (Change the Rsense from power Provider path to power Sink path).  

 

Firmware end, you can re-use the function which is using in VBUS_OCP on power source role. Below example functions your may need to be refer to.

a. Add Function declarations for OCP at file psink.c.

 

static void psnk_dis_ocp(uint8_t port);

static void psnk_shutdown(uint8_t port, bool discharge_dis);

void app_psnk_vbus_ocp_cbk(uint8_t port);

 

b. Add Type-C current level as per Type-C SPEC.

 

/* Type-C current levels in 10mA units. */

#define CUR_LEVEL_3A    300

#define CUR_LEVEL_1_5A  150

#define CUR_LEVEL_DEF   90

 

static const uint32_t cc_rp_to_cur_map[] = {

    CUR_LEVEL_DEF,

    CUR_LEVEL_1_5A,

    CUR_LEVEL_3A

};

 

c. Update psnk_enable function. Example as below with VBUS_OCP_ENABLE

 

void psnk_enable (uint8_t port)

{

    uint8_t intr_state;

   

#if VBUS_OCP_ENABLE

    uint32_t ocp_cur;

#endif

    const dpm_status_t *dpm_stat = dpm_get_info(port);

    intr_state = CyEnterCriticalSection();

 

    if (dpm_get_info(port)->dpm_enabled)

    {

    #if VBUS_OCP_ENABLE

            if (get_pd_port_config(port)->protect_en & CFG_TABLE_OCP_EN_MASK)

            {

                if (dpm_stat->pd_connected)

                {

                    ocp_cur = dpm_stat->snk_cur_level;

                }

                else

                {

                    ocp_cur = cc_rp_to_cur_map[dpm_stat->snk_cur_level];

                }

 

system_vbus_ocp_en(port, ocp_cur, app_psnk_vbus_ocp_cbk);

            }

    #endif /* VBUS_OCP_ENABLE */       

        sink_fet_on(port);

    }

    CyExitCriticalSection(intr_state);

}

 

d. Add a new function for power sink ocp call back.

 

#if VBUS_OCP_ENABLE

void app_psnk_vbus_ocp_cbk(uint8_t port)

{

    /* OCP fault. */

    /* Quickly turning off fets here, although dpm_stop will also do that. */

    psnk_shutdown(port, true);

    /* Stopping dpm before sending app event. If OCP retry logic is enabled, app will

     * restart the dpm. */

    dpm_stop(port);

    /* Enqueue HPI OVP fault event. */

    app_event_handler(port, APP_EVT_VBUS_OCP_FAULT, NULL);

 

}

#endif /* VBUS_OCP_ENABLE */

 

e. Add a new function for power sink OCP disable.

 

static void psnk_dis_ocp(uint8_t port)

{

#if VBUS_OCP_ENABLE

    if (get_pd_port_config(port)->protect_en & CFG_TABLE_OCP_EN_MASK)

    {

        system_vbus_ocp_dis(port);

    }

#endif /* VBUS_OCP_ENABLE */

}

 

f. Add disable OCP when power sink is shut down. Example as below with VBUS_OCP_ENABLE

 

 

static void psnk_shutdown(uint8_t port, bool discharge_dis)

{

    /*Turn Off Source FET*/

    sink_fet_off(port);

 

    if(discharge_dis == true)

    {

        vbus_discharge_off(port);

    }

 

    /* Disable OVP/OCP */

app_ovp_disable (port, false);

#if VBUS_OCP_ENABLE

psnk_dis_ocp(port);

#endif /* VBUS_OCP_ENABLE */

 

}