/**
  *****************************************************************************
  * @file    sys_pd_hook.c
  * @author  Solution Team
  * @version V1.00
  * @date    22-March-2023
  * @brief   USBPD hook implementation
  *****************************************************************************
  * @attention
  *  Copyright (c) 2017 - 2023 Unicmicro Co., Ltd.
  *  All Rights Reserved.
  *****************************************************************************
  */

#include "libc.h"
#include "drivers.h"
#include "sys_pd_config.h"
#include "usbpd.h"
#include "sys_pd_hook.h"
#include "sys_low_power.h"
#include "sys_gpio.h"

#if SYS_QUICK_CHARGE_ENABLED
#include "sys_qc_hook.h"
#else
#if SYS_UFCS_ENABLED
#include "sys_bc_qc_hook.h"
#endif
#endif /* SYS_QUICK_CHARGE_ENABLED */
#include "sys_bat_intf.h"
#include "ufcs.h"

#if SYS_SMG_DISPLAY_ENABLED
#include "sys_smg_display.h"
#endif /* SYS_SMG_DISPLAY_ENABLED */
#include "sys_ex_mcu_ctr.h"

volatile u8_t dpm_ctrl_state = 0;
volatile u8_t dpm_ctrl_mcu_set_state = 0;

#if 0
volatile u8_t mcu_ctrl_state = 0;
volatile u8_t mcu_ctrl_state_pre = 0;
#endif

volatile SYS_PD_INFO_t g_sys_pd_info;

#if (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED)
volatile u32_t dpm_vbat_acum_val = 0;
#define SYS_NUM_OF_VBAT_SCALE				    4
#define SYS_NUM_OF_IBAT_SCALE_FOR_CHARGE		7
#define SYS_NUM_OF_IBAT_SCALE_FOR_DISCHARGE	    9
/* current curve diagram
 * max voltage is: 16.8V (168), see sys_bat_rated_charging_volt_get()
 * and the array defines voltage for capacity 75%, 50%, 25% when charging or discharging
 */

const u16_t const charge_curr_curve[][SYS_NUM_OF_VBAT_SCALE]={
    {16000,15200,14600,13500}, /* for small current, <200mA */
	{16000,15500,14800,14400}, /* for 1A, {volt for 80~60%, 60~40%, 40~20%} value 16000, means 16.0V.*/
	{16400,15900,15300,14800}, /* for 2A */
	{16400,16100,15300,14800}, /* for 3A */
	{16400,16200,15500,15000}, /* for 4A */
	{16700,16500,15900,15500}, /* for 5A */
	{16700,16500,16000,15700} /* for 6A */
	};

const u16_t const discharge_curr_curve[][SYS_NUM_OF_VBAT_SCALE]={
    {15900,15200,14600,13500}, /* for small current, <200mA */
	{15800,15100,14200,13600}, /* for 1A, {volt for 80~60%, 60~40%, 40~20%} value 15600, means 15.6V. */
	{15500,14800,13900,13300}, /* for 2A */
	{15100,14400,13600,12900}, /* for 3A */
	{14900,14100,13400,12800}, /* for 4A */
	{14600,13900,13100,12600}, /* for 5A */
	{14500,13700,12900,12400}, /* for 6A */
	{14100,13300,12600,12100}, /* for 7A */
	{13800,13100,12400,11900} /* for 8A */
	};
#endif

#if  SYS_OVERTEMP_DECTION_ENABLED

/** NOTE: the unit of temperature voltage is 100uV
    温度	电压(V)
    -10	    2.7931
    0	    2.5264
    45	    0.9996
    55	    0.7529
    60	    0.6505
*/

/** Temperature greater than 60C, disable charge and discharge */
#define DPM_TEMP_P60C_VOLT          (2496)//(6505)

/** Temperature greater than 55C, disable charge
 *  Temperature lower than 55C, restore half power charge
 */
#define DPM_TEMP_P55C_VOLT          (2959)//(7529)

/** Temperature greater than 45C, halve charge power
 *  Temperature lower than 45C, restore full power charge
 */
#define DPM_TEMP_P45C_VOLT          (4175)//(9996)

/** Temperature greater than 40C, halve charge power
 *  Temperature lower than 40C, restore full power charge
 */
#define DPM_TEMP_P40C_VOLT          (4961)//(9996)

/** Temperature greater than 0C, restore charge
 *  Temperature lower than 0C, disable charge
 */
#define DPM_TEMP_0C_VOLT            (17199)//(25264)

/** Temperature greater than -10C, restore discharge, but still disable charge
 *  Temperature lower than -10C, disable charge and discharge
 */
#define DPM_TEMP_M5C_VOLT          (19289)//(27931)

#define DPM_TEMP_M10C_VOLT          (27931)

#define DPM_TEMP_INVALID_VOLT       (32600)

#endif /* SYS_OVERTEMP_DECTION_ENABLED */


/*c2 中断处理*/
void sys_gpio_i2c_int_handler()
{
    g_sys_pd_info.i2c_int_flag = TRUE;
#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
    {
        printf("uart1_int_flag=%d\n", g_sys_pd_info.i2c_int_flag);
    }
#endif
}
/*充电断连回调函数*/
void sys_pd_sink_unattached_hook()
{
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
    }
    else {
        sys_gpio_uart0_enable_set(TRUE);
    }
#else
#if SYS_UFCS_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        g_usbc_qc_info.bc_qc_disable = FALSE;
        if (usbpd_cfg_port_quick_charge_ver_get() == DPM_QC_V2)
        {
            g_usbc_qc_info.qc_v3_disabled = TRUE;
        }
        else {
            g_usbc_qc_info.qc_v3_disabled = FALSE;
        }
    }
    else {
        g_usbc_qc_info.bc_qc_disable = TRUE;
    }
    bc_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
    // 关闭UFCS
    ufcs_pe_vbus_present_set(UFCS_USBC_DEV, FALSE);
#else
    sys_gpio_uart0_enable_set(TRUE);
#endif
#endif /* SYS_QUICK_CHARGE_ENABLED */

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSink Unattached Hook");
    }
#endif /* CLI_ENABLED */

    u32_t vbus = sys_bat_vbus_fb_val_get();
    if(vbus > VBUS_VSAFE0V_MAX_VOLT)
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_pd_vbus_discharge_en_set(TRUE);
        delay_ms(100);
        vbus = sys_bat_vbus_fb_val_get();
        if(vbus > 4000)
        {
            delay_ms(100);
        }
    }
    sys_pd_vbus_discharge_en_set(FALSE);

    sys_bat_charge_enable(FALSE);
    sys_gpio_vbus_en_set(FALSE);
    sys_gpio_pmic_pstop_set(FALSE);
    sys_pd_power_policy_process(FALSE);
    sys_gpio_pd_qc_led_off();

    g_sys_pd_info.usbc_src_current_ocp_flg= FALSE;
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;
    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
    gp_usbpd_cfg->port_cfg.epr_mode_en = TRUE;

}

/*充电等待连接回调函数*/
void sys_pd_sink_attachwait_hook()
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSink Attachwait Hook");
    }
#endif /* CLI_ENABLED */
}

/*充电连接成功回调函数*/
void sys_pd_sink_attached_hook()
{
    sys_lpm_activate();

    if (DRV_UART_ID_0 == drv_uart_default_get())
    {
        if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(FALSE);
    }
    else {
        sys_gpio_uart0_enable_set(FALSE);
    }


#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSink Attached Hook");
    }
#endif /* CLI_ENABLED */
#if 0
    if(g_sys_pd_info.usbc_power_ctrl_en)
    {
        if(!g_sys_pd_info.mcu_state.charge_en)
        {
            *(u8_t *)(&g_sys_pd_info.mcu_state) = dpm_ex_pw_ctrl_get();
        }
        if(g_sys_pd_info.mcu_state.charge_en)
        {
            sys_gpio_vbus_en_set(TRUE);
            sys_gpio_pmic_pstop_set(TRUE);
            sys_bat_charge_enable(TRUE);
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
        }
    }
    else
#endif
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_gpio_pmic_pstop_set(TRUE);
        sys_bat_charge_enable(TRUE);
        dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
    }

    g_sys_pd_info.rated_vbus = VSAFE_5V;
    g_sys_pd_info.rated_ibus = CURRENT_3000mA;
    sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
    sys_bat_state_set(SYS_BAT_STATE_CHARGE);
    sys_pd_power_policy_process(TRUE);
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
}

/*充电设备申请新电压回调函数*/
status_t sys_pd_sink_transit_to_new_power_hook()
{
    if (dpm_current_pwr_mode_get())
        return S_ERROR;

    if (!dpm_src_obj_pos_get())
        return S_ERROR;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSink Transit To New Power Hook");
    }
#endif /* CLI_ENABLED */
#if 0
    if(g_sys_pd_info.usbc_power_ctrl_en)
    {
        if(g_sys_pd_info.mcu_state.charge_en)
        {
            sys_bat_charge_enable(TRUE);
        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);
        }
    }
    else
#endif
    {
        sys_bat_charge_enable(TRUE);
    }
    //sys_gpio_pd_qc_led_on();
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

    return S_OK;
}

/*放电断连回调函数*/
void sys_pd_source_unattached_hook()
{
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
    }
    else {
        sys_gpio_uart0_enable_set(TRUE);
    }
#else
#if SYS_UFCS_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        g_usbc_qc_info.bc_qc_disable = FALSE;
        if (usbpd_cfg_port_quick_charge_ver_get() == DPM_QC_V2)
        {
            g_usbc_qc_info.qc_v3_disabled = TRUE;
        }
        else {
            g_usbc_qc_info.qc_v3_disabled = FALSE;
        }
    }
    else {
        g_usbc_qc_info.bc_qc_disable = TRUE;
    }
    bc_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
    // 关闭UFCS
    ufcs_pe_vbus_present_set(UFCS_USBC_DEV, FALSE);
#else
    sys_gpio_uart0_enable_set(TRUE);
#endif
#endif /* SYS_QUICK_CHARGE_ENABLED */

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSrc Unattached Hook");
    }
#endif /* CLI_ENABLED */

    u32_t vbus = sys_bat_vbus_fb_val_get();
    if(vbus > VBUS_VSAFE0V_MAX_VOLT)
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_pd_vbus_discharge_en_set(TRUE);
        delay_ms(100);
        vbus = sys_bat_vbus_fb_val_get();
        if(vbus > 4000)
        {
            delay_ms(100);
        }
    }
    sys_pd_vbus_discharge_en_set(FALSE);

    sys_bat_charge_enable(FALSE);
    sys_gpio_vbus_en_set(FALSE);
    sys_gpio_pmic_pstop_set(FALSE);
    sys_pd_power_policy_process(FALSE);
    sys_gpio_pd_qc_led_off();

    g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
    g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
    g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
    g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
    g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
    g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;

#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;
    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;

    gp_usbpd_cfg->port_cfg.epr_mode_en = TRUE;
    g_sys_pd_info.usbc_src_current_ocp_flg= FALSE;

    gp_usbpd_cfg->port_cfg.dual_role_pwr = TRUE;
}

/*放电等待连接回调函数*/
void sys_pd_source_attachwait_hook()
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSrc Attachwait Hook");
    }
#endif /* CLI_ENABLED */
}

/*放电连接成功回调函数*/
void sys_pd_source_attached_hook()
{
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        if (!dpm_port_dead_battery_get())
        {
            dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
        }
        else {
            drv_chip_dp0_dm0_short_set(TRUE);
        }
    }
    else {
        sys_gpio_uart0_enable_set(TRUE);
    }
#else
#if SYS_UFCS_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        g_usbc_qc_info.bc_qc_disable = FALSE;
        if (usbpd_cfg_port_quick_charge_ver_get() == DPM_QC_V2)
        {
            g_usbc_qc_info.qc_v3_disabled = TRUE;
        }
        else {
            g_usbc_qc_info.qc_v3_disabled = FALSE;
        }
    }
    else {
        g_usbc_qc_info.bc_qc_disable = TRUE;
    }
    if (!dpm_port_dead_battery_get())
    {
        bc_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
    }
    else {
        drv_chip_dp0_dm0_short_set(TRUE);
    }
#endif
#endif /* SYS_QUICK_CHARGE_ENABLED */

    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nSrc Attached Hook");
    }
#endif /* CLI_ENABLED */
#if 0
    if(g_sys_pd_info.usbc_power_ctrl_en)
    {
        if(!g_sys_pd_info.mcu_state.discharge_en)
        {
            *(u8_t *)(&g_sys_pd_info.mcu_state) = dpm_ex_pw_ctrl_get();

        }
        if(g_sys_pd_info.mcu_state.discharge_en)
        {
            sys_gpio_vbus_en_set(TRUE);
            sys_gpio_pmic_pstop_set(TRUE);
            //g_sys_pd_info.vbus_source_en = TRUE;
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;
        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            //g_sys_pd_info.vbus_source_en = FALSE

        }
    }
    else
#endif
    {
        //sys_gpio_vbus_en_set(TRUE);
        //sys_gpio_pmic_pstop_set(TRUE);
        dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;
    }
    g_sys_pd_info.rated_vbus = VSAFE_5V,
    g_sys_pd_info.rated_ibus = 3000;
    if (!dpm_port_dead_battery_get())
    {
        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
    }
    else {
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
    }

    sys_pd_power_policy_process(TRUE);
    sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

    gp_usbpd_cfg->port_cfg.dual_role_pwr = FALSE;
}

/*放电设备设置新电压电流回调函数*/
status_t sys_pd_source_transit_to_new_power_hook(u32_t pos)
{
    u32_t current, voltage;

    if (!dpm_current_pwr_mode_get())
        return S_ERROR;

    if (pos >= CFG_MAX_PWR_CAP_NUM)
        return S_INVALID_PARAMS;

#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
        //dpm_qc_state_set(&g_usbc_qc_info, DPM_QC_DISABLED);
        if (DRV_UART_ID_0 == drv_uart_default_get())
        {
            if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(FALSE);
        }
        else {
            sys_gpio_uart0_enable_set(FALSE);
        }
    }
#endif /* SYS_QUICK_CHARGE_ENABLED */

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        printf("\nSrc Transit To New Power Hook(%u)\n",pos);
    }
#endif /* CLI_ENABLED */

    if (POWER_SUPPLY_TYPE_PPS == usbpd_cfg_port_src_pwr_supply_type_get(pos))
    {
        if (usbpd_cfg_port_src_pps_type_get(pos))
        {
            current = usbpd_cfg_port_src_avs_pwr_max_pdp_get(pos) * 1000000 / usbpd_cfg_port_src_avs_pwr_max_volt_get(pos);
            voltage = REQ_PPS_OUTPUT_VOLT_GET(dpm_current_rdo_get())*VOLTAGE_AVS_REQ_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
        }
        else
        {
            current = usbpd_cfg_port_src_pps_pwr_max_curr_get(pos)*CURRENT_PPS_DIV;
            voltage = REQ_PPS_OUTPUT_VOLT_GET(dpm_current_rdo_get())*VOLTAGE_PPS_REQ_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
        }
    }
    else
    {
        current = usbpd_cfg_port_src_fixed_pwr_curr_cap_get(pos)*CURRENT_DIV;
        voltage = usbpd_cfg_port_src_fixed_pwr_volt_cap_get(pos)*VOLTAGE_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
    }
    
    if (VBUS_CURR_HANDLING_CAP_5A != dpm_rx_vdm_ack_cable_vbus_curr_cap_get())
    {
        if (current > CURRENT_3000mA)
        {
            current = CURRENT_3000mA;
        }
    }

    if(!pe_hard_reset_in_prog())
    {
        g_sys_pd_info.rated_vbus = voltage,
        g_sys_pd_info.rated_ibus = current;
    }

    if (current >= CURRENT_3000mA)
    {
        current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO * current + SYS_POWER_BANK_CURRENT_COMPENSATION;
    }
    else {
        current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * current + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
    }

    /*设置电压电流*/
    sys_bat_discharge_vbus_ibus_set(voltage, current, OUT_DIR);

    //sys_gpio_pd_qc_led_on();

    return S_OK;
}

/*获取vbus使能状态*/
bool_t sys_pd_vbus_source_en_get(void)
{
    return g_sys_pd_info.vbus_source_en;
}

/*打开vbus并输出5v*/
void sys_pd_vbus_source_en_set(bool_t flg)
{
    bool_t old_flg = g_sys_pd_info.vbus_source_en;
    g_sys_pd_info.vbus_source_en = flg ;
    if (!flg)
    {
        sys_gpio_vbus_en_set(FALSE);
        sys_gpio_pmic_pstop_set(FALSE);
    }
    if (old_flg != flg)
	{
#if USBPD_DEBUG_ENABLED
        if (usbpd_cfg_dbg_get() > USBPD_DEBUG_LEVEL_2) 
        {
            printf("\nVBUS_SRC_ON(%u)\n",flg);
        }
#endif /* USBPD_DEBUG_ENABLED */
        if (flg)
        {
            sys_bat_dis_foldback_set(TRUE);
            SYS_BAT_REG_SET(IBAT_LIM_SET_REG,0xFF);
            sys_bat_discharge_vbus_ibus_set(VSAFE_5V+SYS_POWER_BANK_VOLTAGE_COMPENSATION, CURRENT_5000mA, OUT_DIR);
        }
        else {
            sys_bat_dis_foldback_set(FALSE);
            sys_bat_discharge_vbus_ibus_set(SYS_BAT_SC8815_CURRENT_MIN, SYS_BAT_SC8815_CURRENT_MIN, IN_DIR);
        }
    }
    if (flg)
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_gpio_pmic_pstop_set(TRUE);
    }
}

/*获取vbus的电压*/
bool_t sys_usbc_vbus_get()
{
    return (drv_adc_read_multi_avg(SYS_USBC_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBC_VBUS_ADC_CONSTANT )>>12;
}

/*获取电池的电压*/
u16_t sys_adc_vbat_get()
{
    return (drv_adc_read_multi_avg(SYS_USBC_VBAT_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBC_VBUS_ADC_CONSTANT )>>12;
}

/*获取vbus电压泄放使能状态*/
bool_t sys_pd_vbus_discharge_en_get(void)
{
#if 0
    return dpm_vbus_discharge_get();
#else
    return sys_gpio_vbus_discharge_en_get();
#endif
}

/*使能vbus泄放*/
void sys_pd_vbus_discharge_en_set(bool_t flg)
{
#if 0
    dpm_vbus_discharge_set(flg);
#else
    sys_gpio_vbus_discharge_en_set(flg);
#endif
}

bool_t sys_pd_cc1_vconn_en_get(void)
{
    return sys_gpio_vconn1_get();
}

void sys_pd_cc1_vconn_en_set(bool_t flg)
{
    sys_gpio_vconn1_set(flg);
}

bool_t sys_pd_cc2_vconn_en_get(void)
{
    return sys_gpio_vconn2_get();
}

void sys_pd_cc2_vconn_en_set(bool_t flg)
{
    sys_gpio_vconn2_set(flg);
}

void sys_pd_prs_started_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nPRS Started Hook");
    }
#endif /* CLI_ENABLED */

}
void sys_pd_epr_enter_fail_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nepr enter fail Hook");
    }
#endif /* CLI_ENABLED */
    gp_usbpd_cfg->port_cfg.epr_mode_en = FALSE;
}
void sys_pd_prs_completed_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nPRS Completed Hook");
    }
#endif /* CLI_ENABLED */
    if (dpm_current_pwr_mode_get())
    {
        gp_usbpd_cfg->port_cfg.dual_role_pwr = FALSE;
    }
}

void sys_pd_drs_started_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nDRS Started Hook");
    }
#endif /* CLI_ENABLED */

}

void sys_pd_drs_completed_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nDRS Completed Hook");
    }
#endif /* CLI_ENABLED */

}

void sys_pd_vcs_started_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nVCS Started Hook");
    }
#endif /* CLI_ENABLED */

}

void sys_pd_vcs_completed_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nVCS Completed Hook");
    }
#endif /* CLI_ENABLED */

}

void sys_pd_power_change_req_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nPower Change Req Hook");
    }
#endif /* CLI_ENABLED */

}

void sys_pd_prl_msg_received_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_3)
    {
        drv_uart_puts("\nPRL Msg Recevied Hook");
    }
#endif /* CLI_ENABLED */
    g_sys_pd_info.rx_pkt_cnt++;
}

void sys_pd_prl_msg_sent_hook(u32_t arg)
{
    sys_lpm_activate();
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_3)
    {
        drv_uart_puts("\nPRL Msg Sent Hook");
    }
#endif /* CLI_ENABLED */
    g_sys_pd_info.tx_pkt_cnt++;
}

/*led灯状态设置函数*/
void sys_pd_led_state_set(SYS_PD_LED_STATE_t state)
{
    g_sys_pd_info.led_state = state;
    if (state)
    {
        g_sys_pd_info.led_on_start_tick = g_sys_pd_info.continuous_timer_tick;
    }
    if (state == SYS_PD_LED_STATE_FLASH)
    {
        g_sys_pd_info.led_display_flash_interval = 10;
    }
    else if (state == SYS_PD_LED_STATE_FLASH_FAST)
    {
        g_sys_pd_info.led_display_flash_interval = 10;
    }
}

/*功率分配函数*/
#if (!SYS_POWER_POLICY_DISABLED)
void sys_pd_power_policy_process(bool_t change_asap)
{
    if (sys_bat_capacity_get() >= 20)
    {
        g_sys_pd_info.previous_profile = usbpd_cfg_port_src_fixed_pwr_prof_get();

        if (pe_pd_connected_get() || change_asap)
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
                if (POWER_PROFILE_140W_AVS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                {
                    usbpd_cfg_port_epr_mode_en_set(TRUE);
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_140W_AVS);
                }
            }
            else if(POWER_MODE_SINK == dpm_current_pwr_mode_get())
            {
                if (usbpd_cfg_port_epr_mode_en_get())
                {
                    usbpd_cfg_port_epr_mode_en_set(TRUE);
                }
            }
        }
        else if(!dpm_cable_detect_done_get())
        {
            if (POWER_PROFILE_140W_AVS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                usbpd_cfg_port_epr_mode_en_set(TRUE);
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_140W_AVS);
            }
        }
    }
    else
    {
        if (pe_pd_connected_get() || change_asap)
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
#if 0
                if (dpm_port_epr_mode_get())
                {
                    dpm_epr_mode_exit_req_set(TRUE);
                }
#endif
                usbpd_cfg_port_epr_mode_en_set(FALSE);
                if (POWER_PROFILE_100W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                {
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_PPS);
                }
            }
        }
        else if(!dpm_cable_detect_done_get())
        {
            usbpd_cfg_port_epr_mode_en_set(TRUE);
            if (POWER_PROFILE_100W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_PPS);
            }
        }
    }
    /*src连接状态更换pdo*/
    // Change C1 power
    if (usbpd_cfg_port_src_fixed_pwr_prof_changed_flag_get())
    {
        if ((dpm_cable_detect_done_get()) &&
            (dpm_current_pwr_mode_get()) &&
            ((pe_state_get() == PE_SRC_READY)||
            (dpm_port_epr_mode_get())))
        {
#if 1
#if 0  /* modified by James Gan - 2019-12-19 */
            if ((dpm_partner_prod_type_get() == UPD_PRODUCT_HUB)||
                (dpm_partner_prod_type_get() == UPD_PRODUCT_AMA))
            {
                dpm_source_cap_change_set(TRUE);
                dpm_hrst_due_to_no_current_flag_set(FALSE);
            }
            else {
                dpm_hard_reset_req_set(TRUE);
            }
#else
           if (!dpm_port_epr_mode_get())
           {
                dpm_source_cap_change_set(TRUE);
                dpm_hrst_due_to_no_current_flag_set(FALSE);
           }
           else
           {
                /*使能pd的hardreset流程*/
                dpm_hard_reset_req_set(TRUE);
           }

#endif /* #if 0 */
            /*pd的pe状态机函数*/
            pe_state_machine();
#else
            pe_error_recovery_directed_set(TRUE);
#endif
        }
        usbpd_cfg_port_src_fixed_pwr_prof_changed_flag_set(FALSE);
#if CLI_ENABLED
	    if (sys_cfg_dbg_get() >= SYS_DEBUG_LEVEL_2) printf("C1 pf=%u, cap=%u\n", usbpd_cfg_port_src_fixed_pwr_prof_get(), sys_bat_capacity_get());
#endif /* CLI_ENABLED */
    }
}
#endif /* (!SYS_POWER_POLICY_DISABLED) */

#if SYS_POWER_BANK_ENABLED
/*8815获取电池电压函数，最大值25.2v*/
void sys_bat_vbat_update()
{
    #define SYS_VBAT_MAX_MISS_CNT       (30)
    static int vbat_val_miss_cnt = 0;

    // Battery i2c communication check
    sys_bat_current_vbat_val_set(sys_adc_vbat_get());
    if ((I2C_BUS_ERROR == g_i2c_info[SYS_BAT_PWR_CTRL_I2C].last_status) ||
        (I2C_ARBITRATION_LOST == g_i2c_info[SYS_BAT_PWR_CTRL_I2C].last_status) ||
        (I2C_TIME_OUT == g_i2c_info[SYS_BAT_PWR_CTRL_I2C].last_status))
    {
        vbat_val_miss_cnt++;
        if (vbat_val_miss_cnt >= SYS_VBAT_MAX_MISS_CNT)
        {
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_ERR_SET;
#if CLI_ENABLED
			if (sys_cfg_dbg_get()) drv_uart_puts("I2C Fault");
#endif /* CLI_ENABLED */
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
        	sys_capacity_set(sys_bat_capacity_get());
			sys_capacity_para_save();
#endif
            dpm_cc_state_release();
            dpm_cc_state_init();
            drv_chip_reset();
        }
    }
    else {
        vbat_val_miss_cnt = 0;
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_ERR_MASK;
    }
}

/*电量检测函数*/
void sys_bat_capacity_check()
{
/*电池电流补偿*/
#if 1
    if ((!dpm_cable_detect_done_get()))
    {
    #if 0
        if ((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val >SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {
            sys_bat_current_ibat_val_inc( 90);
        }
        else if((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val <= SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {
            sys_bat_current_ibat_val_inc( 60);
        }
        else if((g_sys_pd_info.usba_ibus_avg_val <= SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val > SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {
            sys_bat_current_ibat_val_inc( 60);
        }
        else {
            sys_bat_current_ibat_val_set(SYS_USBA_IBUS_NO_CURRENT_FLOW_THR + (rand() & 0x3));
        }
#endif
    }
    else
    {
        if (sys_bat_current_ibat_val_get() > 300)
        {
            if (sys_bat_charging_flag_get())
            {
                sys_bat_current_ibat_val_inc(90);
            }
            else {
                sys_bat_current_ibat_val_inc(180);
            }
        }
    }
#endif
#if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED
    //电池电量积分函数
    sys_bat_cap_update();
#endif /* SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED */

    sys_bat_accum_ibat_val_inc(sys_bat_current_ibat_val_get());
    sys_bat_accum_val_index_inc(1);

#if USBPD_DEBUG_ENABLED
	if (SYS_DEBUG_LEVEL_3 <= sys_cfg_dbg_get())
    {
        printf("i=%u,v=%u,accum:i=%u,v=%u,idx:%u\n",
        	sys_bat_current_ibat_val_get(), sys_bat_current_vbat_val_get(),
        	sys_bat_accum_ibat_val_get(), sys_bat_accum_vbat_val_get(),
        	sys_bat_accum_val_index_get());
	}
#endif

    if (sys_bat_accum_val_index_get() >= SYS_BAT_ACCUM_VAL_IDX_MAX)
    {
        sys_bat_avg_ibat_val_set(sys_bat_accum_ibat_val_get() / sys_bat_accum_val_index_get());
        sys_bat_accum_ibat_val_set(0);
        sys_bat_accum_val_index_set(0);

        /*电量低于5%闪烁报警*/
        if (sys_bat_capacity_get() <= 5)
        {
            if ((!dpm_port_dead_battery_get()) && (SYS_BAT_STATE_CHARGE != sys_bat_state_get()))
            {
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            }
        }

#if USBPD_DEBUG_ENABLED
    	if (SYS_DEBUG_LEVEL_3 == sys_cfg_dbg_get())
        {
            printf("ibat=%u,vbat=%u,soc=%u,cap=%u\n",
            	sys_bat_current_ibat_val_get(), sys_bat_avg_vbat_val_get(),
                sys_bat_capacity_get(), sys_bat_cap_mws_get());
    	}
#endif
        //sys_pd_power_policy_process(FALSE);
    }
}


#if SYS_LED_ENABLED

#if (!SYS_SMG_DISPLAY_ENABLED)

void sys_pd_init_display()
{
    static u8_t u8_num = SYS_LED_NUM, u8_direction = 1;

#if 0 /*CLI_ENABLED*/
	if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("Init..led %u\n", u8_num);
#endif
	sys_gpio_bat_cap_led_step_on(SYS_LED_NUM-u8_num);
	if (0 == (g_sys_pd_info.continuous_timer_tick % 3))
	{
		if (0 == u8_direction)
		{
			u8_num++;
			if (SYS_LED_NUM == u8_num) u8_direction = 1;
		}
		else {
			u8_num--;
			if (0 == u8_num) u8_direction = 0;
		}
	}
    if ((g_sys_pd_info.sys_initializing) && (0 == u8_num))
    {
        g_sys_pd_info.sys_initializing = FALSE;
        sys_bat_dis_foldback_set(FALSE);
        sys_bat_dis_term_set(FALSE);
        sys_bat_cap_cali();
    }
}
#else
void sys_pd_init_display()
{
    static u8_t u8_num = 8;

#if 0 /*CLI_ENABLED*/
	if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("Init..led %u\n", u8_num);
#endif
	if (0 == (g_sys_pd_info.continuous_timer_tick % 3))
	{
        if (0 == (u8_num & 1))
        {
            sys_smg_display_data_set(188);
        }
        else {
            sys_smg_display_data_set(SMG_NC);
        }
	    u8_num--;
	}
    sys_smg_ctrl_on_set(TRUE);
    if ((g_sys_pd_info.sys_initializing) && (0 == u8_num))
    {
        g_sys_pd_info.sys_initializing = FALSE;
        sys_bat_dis_foldback_set(FALSE);
        sys_bat_dis_term_set(FALSE);
        sys_bat_cap_cali();
    }
}
#endif /* #if (!SYS_SMG_DISPLAY_ENABLED) */

void sys_pd_display_process(void)
{
    if (g_sys_pd_info.display_state)
    {
        if (g_sys_pd_info.sys_initializing)
    	{
    		return;
    	}

        if ((sys_pd_led_state_get() == SYS_PD_LED_STATE_FLASH) ||
            (sys_pd_led_state_get() == SYS_PD_LED_STATE_FLASH_FAST))
        {
#if (!SYS_SMG_DISPLAY_ENABLED)  /* modified by James Gan - 2019-11-25 */
            if ((!dpm_port_dead_battery_get()) && ((sys_bat_capacity_get() > 5)))
            {
                // turn on all LEDs
                sys_gpio_bat_cap_full_led_on();
            }
            else {
                sys_gpio_bat_cap_1st_led_on();
            }
#else
            if ((!dpm_port_dead_battery_get()) && ((sys_bat_capacity_get() > 5)))
            {
                sys_smg_display_data_set(188);
            }
            else {
                sys_smg_display_data_set(sys_bat_capacity_get());
            }
            sys_smg_ctrl_on_set(TRUE);
#endif /* #if (!SYS_SMG_DISPLAY_ENABLED) */
        }
        else {
#if (!SYS_SMG_DISPLAY_ENABLED)  /* modified by James Gan - 2019-11-25 */
#if (5==SYS_LED_NUM)  /* modified by James Gan - 2019-04-16 */
            if (sys_bat_capacity_get() >= 80)
            {
                if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
                {
                    if ((sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_LED_DELAY))
                    {
#if SYS_LED_DISPLAY_DURATION_ENABLED
                        sys_gpio_bat_cap_led_off();
#else
                        sys_gpio_bat_cap_full_led_on();
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */
                        sys_bat_charging_full_flag_set(TRUE);
                    }
                    else if ((sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME))
                    {
                        sys_gpio_bat_cap_full_led_on();
                    }
                    else {
                        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
                        {
                            sys_gpio_bat_cap_4th_led_on();
                        }
                        else {
                            sys_gpio_bat_cap_full_led_on();
                        }
                    }
                }
                else {
                    sys_gpio_bat_cap_full_led_on();
                }
            }
            else if (sys_bat_capacity_get() >= 60)
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_3rd_led_on();
                }
                else {
                    sys_gpio_bat_cap_4th_led_on();
                }
            }
            else if (sys_bat_capacity_get() >= 40)
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_2nd_led_on();
                }
                else {
                    sys_gpio_bat_cap_3rd_led_on();
                }
            }
            else if (sys_bat_capacity_get() >= 20)
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_1st_led_on();
                }
                else {
                    sys_gpio_bat_cap_2nd_led_on();
                }
            }
            else
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_led_off();
                }
                else {
                    sys_gpio_bat_cap_1st_led_on();
                }
            }
#else // 4 LEDs
            if (sys_bat_capacity_get() >= 75)
            {
                if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
                {
                    if ((!g_sys_pd_info.c2_cable_done_flag) &&
                        (g_sys_pd_info.usba_no_current_flow_flag) &&
                        (sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_LED_DELAY))
                    {
#if SYS_LED_DISPLAY_DURATION_ENABLED
                        sys_gpio_bat_cap_led_off();
#else
                        sys_gpio_bat_cap_full_led_on();
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */
                        sys_bat_charging_full_flag_set(TRUE);
                    }
                    else if ((!g_sys_pd_info.c2_cable_done_flag) &&
                        (g_sys_pd_info.usba_no_current_flow_flag) &&
                        (sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME))
                    {
                        sys_gpio_bat_cap_full_led_on();
                    }
                    else {
                        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
                        {
                            sys_gpio_bat_cap_3rd_led_on();
                        }
                        else {
                            sys_gpio_bat_cap_full_led_on();
                        }
                    }
                }
                else {
                    sys_gpio_bat_cap_full_led_on();
                }
            }
            else if (sys_bat_capacity_get() >= 50)
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_2nd_led_on();
                }
                else {
                    sys_gpio_bat_cap_3rd_led_on();
                }
            }
            else if (sys_bat_capacity_get() >= 25)
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_1st_led_on();
                }
                else {
                    sys_gpio_bat_cap_2nd_led_on();
                }
            }
            else
            {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_led_off();
                }
                else {
                    sys_gpio_bat_cap_1st_led_on();
                }
            }
#endif /* #if (5==SYS_LED_NUM) */
#else
            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if ((g_sys_pd_info.led_on_start_tick) &&
                    (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.led_on_start_tick) &&
                    ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.led_on_start_tick) > 10))
                {
                    sys_smg_display_data_set(sys_bat_capacity_get());
                    if ((!g_sys_pd_info.c2_cable_done_flag) &&
                        (g_sys_pd_info.usba_no_current_flow_flag) &&
                        (sys_bat_capacity_get() == 100) &&
                        (sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_LED_DELAY))
                    {
#if SYS_LED_DISPLAY_DURATION_ENABLED
                        sys_smg_display_data_set(SMG_NC);
                        sys_smg_ctrl_on_set(TRUE);
#else
                        sys_smg_ctrl_on_set(TRUE);
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */
                        sys_bat_charging_full_flag_set(TRUE);
                    }
                    else if ((!g_sys_pd_info.c2_cable_done_flag) &&
                        (g_sys_pd_info.usba_no_current_flow_flag) &&
                        (sys_bat_capacity_get() == 100) &&
                        (sys_bat_charging_full_tick_get()) &&
                        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_full_tick_get()) &&
                        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_full_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME))
                    {
                        sys_smg_ctrl_on_set(TRUE);
                    }
                    else {
                        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
                        {
                            sys_smg_display_data_set(SMG_UNITS_DIGIT_OFF + sys_bat_capacity_get());
                            sys_smg_ctrl_on_set(TRUE);
                        }
                        else {
                            sys_smg_ctrl_on_set(TRUE);
                        }
                    }
                }
                else {
                    sys_smg_display_data_set(188);
                    sys_smg_ctrl_on_set(TRUE);
                }
            }
            else {
                sys_smg_display_data_set(sys_bat_capacity_get());
                if ((g_sys_pd_info.prevent_auto_poweroff) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_smg_display_data_set(SMG_X);
                }
                sys_smg_ctrl_on_set(TRUE);
            }
#endif /* #if (!SYS_SMG_DISPLAY_ENABLED) */
        }
    }
    else {
#if SYS_SMG_DISPLAY_ENABLED  /* modified by James Gan - 2019-11-25 */
        sys_smg_display_data_set(SMG_NC);
        sys_smg_ctrl_on_set(TRUE);
#else
        // turn off all LEDs
        sys_gpio_bat_cap_led_off();
#endif /* #if SYS_SMG_DISPLAY_ENABLED */
    }
}

void sys_pd_display_state_machine(void)
{
    // Digit display control
#if SYS_LED_DISPLAY_DURATION_ENABLED
    if ((g_sys_pd_info.led_on_start_tick) &&
        (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.led_on_start_tick) &&
        (((!dpm_port_dead_battery_get()) && ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.led_on_start_tick) > SYS_LED_DISPLAY_DURATION)) ||
         ((dpm_port_dead_battery_get()) && ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.led_on_start_tick) > SYS_LED_DISPLAY_DURATION_SHORT))) &&
        (dpm_port_state_get() != DPM_PORT_STATE_CHARGE))
    {
        g_sys_pd_info.display_state = FALSE;
        sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
    }
    else
#else
    if ((g_sys_pd_info.led_on_start_tick) &&
        (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.led_on_start_tick) &&
        ((dpm_port_dead_battery_get()) && ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.led_on_start_tick) > SYS_LED_DISPLAY_DURATION_SHORT)) &&
        (dpm_port_state_get() != DPM_PORT_STATE_CHARGE))
    {
        g_sys_pd_info.display_state = FALSE;
        sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
    }
    else
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */
    {
        switch (sys_pd_led_state_get())
        {
            case SYS_PD_LED_STATE_FLASH_FAST:
            case SYS_PD_LED_STATE_FLASH:
                if (0 == (g_sys_pd_info.continuous_timer_tick % g_sys_pd_info.led_display_flash_interval))
                {
                    g_sys_pd_info.display_state = FALSE;
                }
                else {
                    g_sys_pd_info.display_state = TRUE;
                }
                break;
            case SYS_PD_LED_STATE_ON:
                if ((g_sys_pd_info.prevent_auto_poweroff) &&
                    (dpm_port_state_get() != DPM_PORT_STATE_CHARGE))
                {
                    if (0 == (g_sys_pd_info.continuous_timer_tick % 30))
                    {
                        g_sys_pd_info.display_state = FALSE;
                    }
                    else {
                        g_sys_pd_info.display_state = TRUE;
                    }
                }
                else {
                    g_sys_pd_info.display_state = TRUE;
                }
                break;
            case SYS_PD_LED_STATE_OFF:
            default:
                g_sys_pd_info.display_state = FALSE;
                break;
        }
    }
}

void sys_pd_display_flash_manually(u8_t cnt, u8_t fast)
{
    sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH);
    // flash n times
    g_sys_pd_info.display_state = TRUE;
    sys_pd_display_process();
    cnt = cnt * 2 - 1;
    do
    {
        // delay about 500ms
        if (!fast)
        {
            rtc_delay_us(300000);
        }
        rtc_delay_us(200000);
        g_sys_pd_info.display_state = !g_sys_pd_info.display_state;
        sys_pd_display_process();
        cnt--;
    } while(cnt > 0);
    rtc_delay_us(200000);
}

#else

#define sys_pd_display_flash_manually(cnt,fast)

#endif /* SYS_LED_ENABLED */

#if SYS_USBA_ENABLED
/*获取usba1的vbus电压*/
u32_t sys_usba1_vbus_get()
{
    return (drv_adc_read_multi_avg(SYS_USBA1_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBA_VBUS_ADC_CONSTANT)>>12;
}
/*获取usba2的vbus电压*/
u32_t sys_usba2_vbus_get()
{
    return drv_adc_read_multi_avg(SYS_USBA2_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBA_VBUS_ADC_CONSTANT / ADC_REF_DIVISOR;
}
/*设置usba的输出电压函数*/
bool_t sys_usba_vbus_set(u32_t volt)
{
    if ((VOLTAGE_12V < volt) || (VOLTAGE_5V > volt))
        return FALSE;

    sync_enter_critical();

    if (VOLTAGE_5V == volt)
    {
        drv_pwm_duty_set(SYS_USBA_PWM_ID, SYS_DEF_USBA_PWM_DUTY_5V, SYS_DEF_USBA_PWM_PER);
    }
    else if (VOLTAGE_9V == volt)
    {
        drv_pwm_duty_set(SYS_USBA_PWM_ID, SYS_DEF_USBA_PWM_DUTY_9V, SYS_DEF_USBA_PWM_PER);
    }
    else if (VOLTAGE_12V == volt)
    {
        drv_pwm_duty_set(SYS_USBA_PWM_ID, SYS_DEF_USBA_PWM_DUTY_12V, SYS_DEF_USBA_PWM_PER);
    }
    else {
        drv_pwm_duty_set(SYS_USBA_PWM_ID, SYS_DEF_USBA_PWM_VOLT_TO_DUTY(volt), SYS_DEF_USBA_PWM_PER);
    }

    drv_pwm_en_set(SYS_USBA_PWM_ID, TRUE);

#if SYS_QUICK_CHARGE_ENABLED
    g_usba1_qc_info.vbus_volt = volt;
#endif /* SYS_QUICK_CHARGE_ENABLED */

    sync_exit_critical();

    return TRUE;
}
/*usba上电初始化函数*/
void sys_usba_init()
{
    // read status reg
    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
#if  0
    if (sys_gpio_usba1_insert_detect_get())
    {
        sys_gpio_usba1_power_on_set(TRUE);
        delay(500);
        sys_gpio_usba1_power_on_set(FALSE);
    }
    if (sys_gpio_usba2_insert_detect_get())
    {
        sys_gpio_usba2_power_on_set(TRUE);
        delay(500);
        sys_gpio_usba2_power_on_set(FALSE);
    }
    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
    g_sys_pd_info.usba1_indet_current_flag = sys_gpio_usba1_insert_detect_get();
    g_sys_pd_info.usba2_indet_current_flag = sys_gpio_usba2_insert_detect_get();

    if (g_sys_pd_info.usba1_indet_current_flag)
    {
        g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_flag;
        g_sys_pd_info.usba1_indet_flag = g_sys_pd_info.usba1_indet_current_flag;
        sys_gpio_usba1_insert_detect_clear();
        //enble 8102
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba1_volt_check_en(TRUE);
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
        if(!g_sys_pd_info.usba2_indet_flag)
        {
             g_sys_pd_info.usba_no_current_flow_flag = FALSE;

        }

#if CLI_ENABLED
        if (sys_cfg_dbg_get()) drv_uart_puts(" A1 indet init ");
#endif /* CLI_ENABLED */

    }
     if (g_sys_pd_info.usba2_indet_current_flag)
    {
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_flag;
        g_sys_pd_info.usba2_indet_flag = g_sys_pd_info.usba2_indet_current_flag;
        sys_gpio_usba2_insert_detect_clear();
        //enble jw5068
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);
        // Enable QC;
        if(g_sys_pd_info.usba1_indet_flag)
        {
            sys_gpio_usba2_qc_enble_set(FALSE);

        }
        else
        {
            sys_gpio_usba2_qc_enble_set(TRUE);
            g_sys_pd_info.usba_no_current_flow_flag = FALSE;
            g_sys_pd_info.usba2_disconnected_tick = 0;
            g_sys_pd_info.usba_no_current_start_tick = 0;

#if CLI_ENABLED
            if (sys_cfg_dbg_get()) drv_uart_puts(" A1 indet init and QC On");
#endif /* CLI_ENABLED */
       }
    }
#endif
}
#endif
#define IBUS_VSAFE5V_OVER_MAX 3500

/*c口的过流保护函数*/
#if SYS_UFCS_ENABLED
void sys_usbc_ibus_ocp()
{
    // C1 over current check
    if (ufcs_pe_identified_get(UFCS_USBC_DEV))
    {
        //ufcs protect
        u32_t ref_curr = ufcs_pe_rx_request_req_curr_get(UFCS_USBC_DEV)*UFCS_CURRENT_DIV;
        //ufcs protect
        if ((ref_curr) && 
            (g_sys_pd_info.vbus_current > (ref_curr*116/100)))
        {
            if(!g_sys_pd_info.ocp_start_tick)
            {
                g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
            }
            sys_gpio_pmic_pstop_set(FALSE);
            sys_gpio_vbus_en_set(FALSE);
            dpm_vbus_source_en_set(FALSE);
            sys_gpio_pd_qc_led_off();
            dpm_source_ocp_flag_set(TRUE);
            sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            if (sys_cfg_dbg_get()) puts("UFCS OCP");
        }
    }
    else
    {
        if ((dpm_vbus_source_en_get()) &&
            (sys_pd_ibus_over_check())&&
            (!pe_hard_reset_in_prog())&&
            (!pe_prs_in_prog_get())&&
            (!dpm_hard_reset_req_get()))
        {
            sys_gpio_pmic_pstop_set(FALSE);
            sys_gpio_vbus_en_set(FALSE);
            dpm_vbus_source_en_set(FALSE);
            sys_gpio_pd_qc_led_off();
            dpm_source_ocp_flag_set(TRUE);
            sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            if (g_sys_pd_info.ocp_restore_cnt < 1)
            {
                g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
            }
            else
            {
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            }
        }
    }
}
#else
void sys_usbc_ibus_ocp()
{
    // C1 over current check
    if ((dpm_vbus_source_en_get()) &&
        (sys_pd_ibus_over_check())&&
        (!pe_hard_reset_in_prog())&&
        (!pe_prs_in_prog_get())&&
        (!dpm_hard_reset_req_get()))
    {
        sys_gpio_pmic_pstop_set(FALSE);
        sys_gpio_vbus_en_set(FALSE);
        dpm_vbus_source_en_set(FALSE);
        sys_gpio_pd_qc_led_off();
        dpm_source_ocp_flag_set(TRUE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        if (g_sys_pd_info.ocp_restore_cnt < 1)
        {
            g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
        }
        else
        {
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
        }
    }
}
#endif
#if SYS_USBA_ENABLED
/*usba 重新加载函数*/
void sys_usba_restore()
{
    if (g_sys_pd_info.usba2_indet_flag &&(!g_sys_pd_info.usba1_indet_flag))
    {
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);
        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba2_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 On\n");
#endif /* CLI_ENABLED */
    }
    else if(g_sys_pd_info.usba1_indet_flag&&(!g_sys_pd_info.usba2_indet_flag))
    {
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba1_volt_check_en(TRUE);

        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 Off, A1  On\n");
#endif /* CLI_ENABLED */
    }
    else if(g_sys_pd_info.usba2_indet_flag && g_sys_pd_info.usba1_indet_flag)
    {
        sys_gpio_usba_dc_enble_set(TRUE);

        sys_gpio_usba2_qc_enble_set(FALSE);

        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);

        sys_gpio_usba1_volt_check_en(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);

        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba2_disconnected_tick = 0;
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
 #if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 on, A1  On\n");
#endif /* CLI_ENABLED */
    }
}
#endif
#endif /* SYS_POWER_BANK_ENABLED */
/*电源按键检测函数*/
void power_key_event_detect()
{
    g_sys_pd_info.power_check_current_state = sys_gpio_power_check_detect();

    if (g_sys_pd_info.power_check_current_state)
    {
        if (g_sys_pd_info.power_check_current_state != g_sys_pd_info.power_check_last_state)
        {
            g_sys_pd_info.power_check_last_state = g_sys_pd_info.power_check_current_state;
#if CLI_ENABLED
            if (sys_cfg_dbg_get())
            {
                printf("\nPWR_CHK detected\n");
            }
#endif

#if SYS_POWER_KEY_DOUBLE_CLICK_CTRL
    		g_sys_pd_info.key_down_cnt++;
#if CLI_ENABLED
    		if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2) printf("PWR_CHK det,%u\n", g_sys_pd_info.key_down_cnt);
#endif
#endif
        }
    }
    else {
#if SYS_POWER_KEY_DOUBLE_CLICK_CTRL
    	if(1 == g_sys_pd_info.key_down_cnt)
    	{
    		if(0 == g_sys_pd_info.double_click_1st_hit_tick)
    		{
    			//printf ("wait another K-down,%u\n", g_sys_pd_info.key_down_cnt);
    			g_sys_pd_info.double_click_1st_hit_tick = g_sys_pd_info.continuous_timer_tick;
    		}
            else if ((g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.double_click_1st_hit_tick) &&
    		    ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.double_click_1st_hit_tick) >= 8))
    		{
    			g_sys_pd_info.double_click_1st_hit_tick = 0;
    			g_sys_pd_info.key_down_cnt = 0;
    			//printf ("d-click time o,%u\n", g_sys_pd_info.key_down_cnt);
    		}
    	}
        else if ((1 < g_sys_pd_info.key_down_cnt) && g_sys_pd_info.double_click_1st_hit_tick &&
    	    (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.double_click_1st_hit_tick) &&
    	    ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.double_click_1st_hit_tick) < 8))
    	{
            if (g_sys_pd_info.prevent_auto_poweroff)
            {
                g_sys_pd_info.prevent_auto_poweroff = FALSE;
                g_sys_pd_info.low_current_mode_start_tick = 0;
                sys_hub_ctrl_set(FALSE);
                sys_gpio_hub_led_off();
            }
            else {
                sys_hub_ctrl_set(TRUE);
                sys_gpio_hub_led_on();
                g_sys_pd_info.prevent_auto_poweroff = TRUE;
                if (!g_sys_pd_info.low_current_mode_start_tick)
                {
                    g_sys_pd_info.low_current_mode_start_tick = g_sys_pd_info.continuous_timer_tick;
                }
            }
    		g_sys_pd_info.double_click_1st_hit_tick = 0;
    		g_sys_pd_info.key_down_cnt = 0;
    	}
        else
    	{
    		g_sys_pd_info.double_click_1st_hit_tick = 0;
    		g_sys_pd_info.key_down_cnt = 0;
    	}
#endif
        g_sys_pd_info.power_check_last_state = FALSE;
    }
}

/*QC状态机入口函数*/
#if SYS_QUICK_CHARGE_ENABLED
void sys_qc_machine_entrence()
{
    if (usbpd_cfg_port_quick_charge_en_get())
    {
#if SYS_USBA_ENABLED
        if (g_sys_pd_info.usba1_qc_en_flag)
        {
            dpm_qc_state_machine(&g_usba1_qc_info);
        }
#endif
        if ((!pe_pd_connected_get()) &&
            (dpm_current_pwr_mode_get()) &&
            (DPM_QC_DISABLED != dpm_qc_state_get(&g_usbc_qc_info)))
        {
            dpm_qc_state_machine(&g_usbc_qc_info);
        }
    }
}
#endif
/*延迟系统初始化函数，获取电池电量*/
void sys_init_config()
{
    // after system init 1.0 seconds, we need to enable short foldback feature
    if (10 <= g_sys_pd_info.continuous_timer_tick)
    {
        g_sys_pd_info.sys_initializing = FALSE;
        sys_bat_dis_foldback_set(FALSE);
        sys_bat_dis_term_set(FALSE);
        sys_bat_cap_cali();
    }
}
/*USBC过压欠压保护*/
#if SYS_UFCS_ENABLED
void sys_usbc_vbus_ovp_hanler()
{
    // C1 over voltage or short protection check
    if (ufcs_pe_identified_get(UFCS_USBC_DEV))
    {
        u32_t ref_volt = ufcs_pe_rx_request_req_volt_get(UFCS_USBC_DEV)*UFCS_VOLTAGE_DIV;
        //ufcs protect
        if ((ref_volt) && 
            (g_sys_pd_info.vbus_current < (ref_volt*85/100)))
        {
            if(!g_sys_pd_info.ovp_start_tick)
            {
                g_sys_pd_info.ovp_start_tick = g_sys_pd_info.continuous_timer_tick;
            }
        }
        else {
            g_sys_pd_info.ovp_start_tick = 0;
        }
    }
    else
    {
        if ((dpm_vbus_source_en_get()) &&
            (dpm_cable_detect_done_get()) &&
            (!dpm_source_ocp_flag_get()) &&
            (dpm_current_pwr_mode_get()) &&
            (!pe_hard_reset_in_prog()) &&
            (!dpm_hard_reset_req_get()) &&
            (!pe_prs_in_prog_get()) &&
            (((pe_ps_ready_start_time_get()) && ((u32_t)(now() - pe_ps_ready_start_time_get()) > 2000000UL))||
            ((!pe_pd_connected_get())&&(pe_state_get()!= PE_SRC_TRANSIT_TO_DEFAULT))) &&
            (dpm_src_ocp_vbus_drop_check()))
        {
            if(!g_sys_pd_info.ovp_start_tick)
            {
                g_sys_pd_info.ovp_start_tick = g_sys_pd_info.continuous_timer_tick;
            }
        }
        else
        {
            g_sys_pd_info.ovp_start_tick = 0;
        }
    }

    if (g_sys_pd_info.ovp_start_tick &&
        ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.ovp_start_tick) > 20))
    {
        g_sys_pd_info.ovp_start_tick = 0;
        sys_gpio_pmic_pstop_set(FALSE);
        sys_gpio_vbus_en_set(FALSE);
        dpm_vbus_source_en_set(FALSE);
        sys_gpio_pd_qc_led_off();
        dpm_source_ocp_flag_set(TRUE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        if (g_sys_pd_info.ocp_restore_cnt < 1)
        {
            g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
        }
        else
        {
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
        }

#if CLI_ENABLED
        if (sys_cfg_dbg_get()) puts("Short Protection\n");
#endif /* CLI_ENABLED */
    }
}
#else
void sys_usbc_vbus_ovp_hanler()
{
// C1 over voltage or short protection check
    if ((dpm_vbus_source_en_get()) &&
        (dpm_cable_detect_done_get()) &&
        (!dpm_source_ocp_flag_get()) &&
        (dpm_current_pwr_mode_get()) &&
        (!pe_hard_reset_in_prog()) &&
        (!dpm_hard_reset_req_get()) &&
        (!pe_prs_in_prog_get()) &&
        (((pe_ps_ready_start_time_get()) && ((u32_t)(now() - pe_ps_ready_start_time_get()) > 2000000UL))||
        ((!pe_pd_connected_get())&&(pe_state_get()!= PE_SRC_TRANSIT_TO_DEFAULT))) &&
        (dpm_src_ocp_vbus_drop_check()))
    {
        if(!g_sys_pd_info.ovp_start_tick)
        {
            g_sys_pd_info.ovp_start_tick = g_sys_pd_info.continuous_timer_tick;
        }
    }
    else
    {
        g_sys_pd_info.ovp_start_tick = 0;
    }

    if(g_sys_pd_info.ovp_start_tick &&
        ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.ovp_start_tick) > 20))
    {
        g_sys_pd_info.ovp_start_tick = 0;
        sys_gpio_pmic_pstop_set(FALSE);
        sys_gpio_vbus_en_set(FALSE);
        dpm_vbus_source_en_set(FALSE);
        sys_gpio_pd_qc_led_off();
        dpm_source_ocp_flag_set(TRUE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        if (g_sys_pd_info.ocp_restore_cnt < 1)
        {
            g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
        }
        else
        {
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
        }

#if CLI_ENABLED
        if (sys_cfg_dbg_get()) puts("Short Protection\n");
#endif /* CLI_ENABLED */
    }
}
#endif
/*过流保护恢复函数*/
void sys_usbc_ocp_restore()
{
    if ((g_sys_pd_info.ocp_start_tick) &&
        (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.ocp_start_tick >= SYS_OCP_RESTORE_TIME)&&
        (g_sys_pd_info.ocp_restore_cnt < 1))
    {
        g_sys_pd_info.ocp_start_tick = 0;
        g_sys_pd_info.ocp_restore_cnt++;
        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
#if CLI_ENABLED
        if (sys_cfg_dbg_get()) puts("Auto restore");
#endif /* CLI_ENABLED */

        // restore OCP
        if (dpm_source_ocp_flag_get())
        {
            dpm_source_ocp_flag_set(FALSE);
#if CLI_ENABLED
            if (sys_cfg_dbg_get()) puts("Restore C1");
#endif /* CLI_ENABLED */
            if(g_sys_pd_info.mcu_state.discharge_en)
            {
                sys_gpio_pmic_pstop_set(TRUE);
                sys_gpio_vbus_en_set(TRUE);
                if (pe_pd_connected_get())
                {
                  dpm_hard_reset_req_set(TRUE);
                  pe_state_machine();
                }
                else
                {
                    dpm_vbus_source_en_set(TRUE);
     #if SYS_QUICK_CHARGE_ENABLED
                    if (usbpd_cfg_port_quick_charge_en_get())
                    {
                        dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
                    }
#endif
                }
            }
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;
        }
    }
}
/*电池低电量保护函数*/
void sys_deadbattery_protection()
{
    if ((!sys_bat_charging_flag_get()) &&
        (!pe_prs_in_prog_get()) &&
        (!dpm_port_dead_battery_get()) &&
        ((sys_bat_current_vbat_val_get() > SYS_BAT_INVALID_VOLT)))
    {
        if (usbpd_cfg_port_bat_cell_get() == SYS_BAT_4S)
        {
            if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_4S)
            {
                sys_bat_dead_check_cnt_inc(1);
            }
            else
            {
                sys_bat_dead_check_cnt_set(0);
            }
        }
        else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_5S)
        {
            if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_5S)
            {
                sys_bat_dead_check_cnt_inc(1);
            }
            else{
                sys_bat_dead_check_cnt_set(0);
            }
        }
        else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_6S)
        {
            if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_6S)
            {
                sys_bat_dead_check_cnt_inc(1);
            }
            else
            {
                sys_bat_dead_check_cnt_set(0);
            }
        }
        else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_7S)
        {
            if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_7S)
            {
                sys_bat_dead_check_cnt_inc(1);
            }
            else
            {
                sys_bat_dead_check_cnt_set(0);
            }
        }
        else if(usbpd_cfg_port_bat_cell_get() < SYS_BAT_4S)
        {
            if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_UNDER_4S)
            {
                sys_bat_dead_check_cnt_inc(1);
            }
            else
            {
                sys_bat_dead_check_cnt_set(0);
            }
        }
        if (sys_bat_dead_check_cnt_get() >= SYS_POWER_BANK_CHECK_DEAD_BATTERY_CNT)
        {
            dpm_port_dead_battery_set(TRUE);
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_LCP_SET;
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;

#if CLI_ENABLED
            if (sys_cfg_dbg_get()) printf("EX Dead Bat:%umV\n",sys_bat_current_vbat_val_get());
#endif /* CLI_ENABLED */

            if (DPM_CC_ATTACHED_SRC == dpm_cc_state_get())
            {
                dpm_vbus_source_en_set(FALSE);
            }
            // disable USB-A
            //sys_usba_vbus_set(VOLTAGE_5V);
            sys_gpio_usba1_power_on_set(FALSE);
            sys_gpio_usba2_power_on_set(FALSE);
            sys_gpio_usba_c2_enble_set(FALSE);
            //Need to flash battery cap LEDs to notice dead battery
            //sys_gpio_pd_qc_led_off();
            sys_bat_state_set(SYS_BAT_STATE_DEAD_BATTERY);
            sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            sys_bat_dead_check_cnt_set(0);
        }
    }
}
/*电池充放电方向检测函数*/
void detect_current_direction()
{
    // get ibat value
    g_sys_bat_info.current_ibat_val = sys_bat_ibat_val_get();
    g_sys_pd_info.vbus_current = sys_bat_vbus_fb_val_get();
    g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();

    // C1 power
    g_sys_pd_info.c1_current_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current;
    // A port power
    u32_t usba_pwr = 0;
#if SYS_USBA_ENABLED
    if (g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR)
    {
        usba_pwr = g_sys_pd_info.usba_ibus_avg_val + 50;

        usba_pwr = usba_pwr * sys_usba1_vbus_get() / SYS_BAT_DISCHARGING_EFFICIENCY;
    }
#endif
    if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
    {
        // available charge power
        dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_CHG_SET;
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        g_sys_pd_info.c1_current_pwr *= SYS_BAT_CHARGING_EFFICIENCY;

        if (g_sys_pd_info.c1_current_pwr > usba_pwr)
        {
            sys_bat_charging_flag_set(TRUE);
            if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
            {
                sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
        		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
            }
            sys_bat_state_set(SYS_BAT_STATE_CHARGE);
            //sys_bat_current_ibat_val_set((g_sys_pd_info.c1_current_pwr - usba_pwr) / sys_bat_current_vbat_val_get());
        }
        else {
            sys_bat_charging_flag_set(FALSE);
            if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
            {
                sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
        		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
                sys_bat_charging_full_flag_set(FALSE);
                sys_bat_charging_full_tick_set(0);
            }
            sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
            //sys_bat_current_ibat_val_set((usba_pwr - g_sys_pd_info.c1_current_pwr) / sys_bat_current_vbat_val_get());
        }
    }
    else {
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_CHG_MASK;
        sys_bat_charging_flag_set(FALSE);
        g_sys_pd_info.c1_current_pwr = g_sys_pd_info.c1_current_pwr / SYS_BAT_DISCHARGING_EFFICIENCY;
        //sys_bat_current_ibat_val_set((usba_pwr + g_sys_pd_info.c1_current_pwr) / sys_bat_current_vbat_val_get());
        if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
        {
    		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
    		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
            sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        }
        if ((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR) ||
            (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE))
        {
            sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        }
        else if ((g_sys_pd_info.usba_ibus_avg_val <= SYS_USBA_IBUS_NO_CURRENT_FLOW_THR) &&
            (dpm_port_state_get() == DPM_PORT_STATE_IDLE))
        {
            sys_bat_state_set(SYS_BAT_STATE_IDLE);
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_SYS_IDLE_SET;
        }
    }
}
/*强制hard reset函数*/
void pd_hard_reset_need_check()
{
    if ((dpm_cable_detect_done_get()) &&
        (dpm_current_pwr_mode_get()) &&
        (pe_pd_connected_time_get()) &&
        ((u32_t)(now() - pe_pd_connected_time_get()) > 3000000UL) &&
        (!dpm_hrst_due_to_no_current_flag_get()) &&
        (POWER_PROFILE_30W_FIXED <= usbpd_cfg_port_src_fixed_pwr_prof_get()) &&
        (dpm_src_obj_pos_get() > 1) &&
        (10 < g_sys_pd_info.ibus_current) && (g_sys_pd_info.ibus_current < 150))
    {
        dpm_hrst_due_to_no_current_flag_set(TRUE);
        dpm_hard_reset_req_set(TRUE);
#if CLI_ENABLED
        if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1)
        {
            printf ("Need to hrst due to no current.\n");
        }
#endif
    }
/* SYS_POWER_SOURCE_NO_CURRENT_HRST */
}
/*电源按键事件处理函数*/
void powerkey_event_hander()
{
    g_sys_pd_info.power_down_detect_current_state = g_sys_pd_info.power_check_current_state;

    if (g_sys_pd_info.power_down_detect_current_state)
    {
        if (g_sys_pd_info.power_down_detect_current_state != g_sys_pd_info.power_down_detect_last_state)
        {
            g_sys_pd_info.power_down_detect_last_state = g_sys_pd_info.power_down_detect_current_state;
            g_sys_pd_info.power_down_detect_start_time = g_sys_pd_info.current_time;
            g_sys_pd_info.auto_power_down_last_tick = 0;

            if (dpm_port_dead_battery_get() && (!sys_bat_charging_flag_get()))
            {
                sys_bat_state_set(SYS_BAT_STATE_DEAD_BATTERY);
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            }
            else {
                sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                if(!sys_gpio_usba_c2_enble_get())
                {
                    sys_gpio_usba_c2_enble_set(TRUE);
                    g_sys_pd_info.usba_no_current_start_tick = g_sys_pd_info.continuous_timer_tick;
                    g_sys_pd_info.usbc2_no_current_start_tick = g_sys_pd_info.continuous_timer_tick;
                }
            }

            if (sys_bat_charging_full_tick_get() && (g_sys_pd_info.continuous_timer_tick > SYS_BAT_CHARGE_FULL_DETETION_TIME))
            {
                sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick - SYS_BAT_CHARGE_FULL_DETETION_TIME);
            }

            if ((!dpm_port_dead_battery_get()) && (!g_sys_pd_info.p60c_otp_flag) && (!g_sys_pd_info.m10c_otp_flag))
            {
                // restore OCP
                if (g_sys_pd_info.usba_no_current_flow_flag && g_sys_pd_info.usba_ocp_flag)
                {
                    g_sys_pd_info.usba_ocp_flag = FALSE;
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Restore USB when no OCP\n");
#endif /* CLI_ENABLED */
                    //sys_usba_restore();
                }

                if (dpm_source_ocp_flag_get()||g_sys_pd_info.usbc_src_current_ocp_flg)
                {
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Restore C1 when no OCP\n");
#endif /* CLI_ENABLED */
                    dpm_source_ocp_flag_set(FALSE);
                    g_sys_pd_info.usbc_src_current_ocp_flg = FALSE;
                    sys_gpio_pmic_pstop_set(TRUE);
                    sys_gpio_vbus_en_set(TRUE);
                    dpm_vbus_source_en_set(TRUE);

                    if (dpm_cable_detect_done_get() &&
                        pe_pd_connected_get())
                    {
                        if (dpm_port_epr_mode_get())
                        {
                            pe_error_recovery_directed_set(TRUE);
                        }
                        else{
                            dpm_hard_reset_req_set(TRUE);
                            pe_state_machine();
                        }
                    }
                }
            }
        }

        if ((dpm_port_state_get() != DPM_PORT_STATE_CHARGE) &&
            (g_sys_pd_info.power_down_detect_last_state) &&
            (g_sys_pd_info.power_down_detect_start_time) &&
            (g_sys_pd_info.current_time > g_sys_pd_info.power_down_detect_start_time) &&
            ((g_sys_pd_info.current_time - g_sys_pd_info.power_down_detect_start_time) > SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION))
        {
            g_sys_pd_info.power_down_detect_last_state = FALSE;
#if CLI_ENABLED
			if (sys_cfg_dbg_get()) printf("Off\n");
#endif /* CLI_ENABLED */
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
            sys_capacity_set(sys_bat_capacity_get());
            sys_capacity_reset_flag_set(FALSE);
			sys_capacity_para_save();
#endif
            if (dpm_port_dead_battery_get())
            {
                dpm_port_dead_battery_set(FALSE);
                sys_bat_state_set(SYS_BAT_STATE_IDLE);
            }

            sys_pd_display_flash_manually(3,FALSE);
            sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
            while (sys_gpio_power_check_detect())
            {
                if ((now() - g_sys_pd_info.power_down_detect_start_time) > SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
                {
                    sys_pd_display_flash_manually(3,TRUE);
                }
            }
            if ((now() - g_sys_pd_info.power_down_detect_start_time) > SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
            {
                sys_cfg_erase();
                sys_capacity_para_erase();
            }

             //disable 8812 pstop
            sys_gpio_pmic_pstop_set(FALSE);
            // 8812 ad_start set 1
            SYS_BAT_REG_FIELD_SET(CTRL3_SET_REG,AD_START,FALSE);
            sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
            SYS_BAT_REG_SET(MASK_REG,0x8e);
            printf("MASK_REG=0x%x\n",SYS_BAT_REG_GET(MASK_REG));
            //usba indet1 indet2 mask set 1
            // disable USB-A
            //sys_gpio_usba_dc_enble_set(FALSE);
           // sys_gpio_usba2_qc_enble_set(FALSE);
            //sys_gpio_usba1_power_on_set(FALSE);
           // sys_gpio_usba2_power_on_set(FALSE);
            //sys_gpio_usba1_volt_check_en(TRUE);
           // sys_gpio_usba2_volt_check_en(TRUE);
            sys_gpio_usba_c2_enble_set(FALSE);
            sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
            printf("STATUS_REG=0x%x\n",SYS_BAT_REG_GET(STATUS_REG));
            dpm_cc_state_release();
            dpm_cc_state_init();
            dpm_rp_rd_clear();
            //sys_cmd_port_disable_set(TRUE);
            rtc_delay_us(1000000UL);
            DRV_INTR_GLOBAL_DISABLE();
            sys_gpio_power_on_set(OFF);
            sys_tick_t power_off = now();
            while(1)
	        {
				if((now()-power_off)>SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
				{
					break;
				}
			}
            drv_chip_reset();
        }
    }
    else {
        g_sys_pd_info.power_down_detect_last_state = 0;
        g_sys_pd_info.power_down_detect_start_time = 0;
    }

}
#if SYS_USBA_ENABLED
/*USBA电流检测函数*/
void usba_current_check()
{
    g_sys_pd_info.usba_ibus_accum_val += sys_usba_ibus_get();
    g_sys_pd_info.usba_ibus_accum_val_idx++;
    if (g_sys_pd_info.usba_ibus_accum_val_idx >= SYS_USBA_IBUS_ACCUM_VAL_IDX_MAX)
    {
        g_sys_pd_info.usba_ibus_avg_val = g_sys_pd_info.usba_ibus_accum_val / g_sys_pd_info.usba_ibus_accum_val_idx;
    	g_sys_pd_info.usba_ibus_accum_val = 0;
        g_sys_pd_info.usba_ibus_accum_val_idx = 0;

        g_sys_pd_info.usba_no_current_flow_last_flag = g_sys_pd_info.usba_no_current_flow_flag;
        if (g_sys_pd_info.usba_ibus_avg_val <= SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)
        {
            g_sys_pd_info.usba_no_current_flow_flag = TRUE;
        }
        else if ((g_sys_pd_info.usba_ibus_avg_val >= SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR)&&
            (sys_gpio_usba_c2_enble_get()))
        {
            g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        }
        if (g_sys_pd_info.usba_no_current_flow_last_flag != g_sys_pd_info.usba_no_current_flow_flag)
        {
            if (!g_sys_pd_info.usba_no_current_flow_flag)
            {
                sys_bat_dis_term_set(TRUE);
                sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                g_sys_pd_info.usba_no_current_start_tick = 0;
            }
            else {
                if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE))
                {
                    sys_bat_dis_term_set(FALSE);
                    if (sys_bat_charging_full_tick_get() && (g_sys_pd_info.continuous_timer_tick > SYS_BAT_CHARGE_FULL_DETETION_TIME))
                    {
                        sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick - SYS_BAT_CHARGE_FULL_DETETION_TIME);
                    }
                    sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                }
                g_sys_pd_info.usba_no_current_start_tick = g_sys_pd_info.continuous_timer_tick;
            }
        }
     }
}
#endif
/*系统自动关机检测函数*/
void chip_auto_power_off()
{
    if (usbpd_cfg_port_auto_power_down_get())
    {
#if SYS_POWER_KEY_DOUBLE_CLICK_CTRL  /* modified by James Gan - 2019-01-15 */
    	if ((!dpm_cable_detect_done_get()) &&
            (((FALSE == g_sys_pd_info.prevent_auto_poweroff) && (g_sys_pd_info.usba_no_current_flow_flag && g_sys_pd_info.usbc2_no_current_flow_flag)) ||
             (g_sys_pd_info.prevent_auto_poweroff && g_sys_pd_info.low_current_mode_start_tick &&
             (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.low_current_mode_start_tick) &&
             ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.low_current_mode_start_tick) > SYS_LOW_CURRENT_MODE_FORCE_POWER_OFF_TIME))))
#else
    	if (!dpm_cable_detect_done_get())
#endif /* #if SYS_POWER_KEY_DOUBLE_CLICK_CTRL */
        {
            if (!g_sys_pd_info.auto_power_down_last_tick)
            {
                g_sys_pd_info.auto_power_down_last_tick = g_sys_pd_info.continuous_timer_tick;
            }

            if (g_sys_pd_info.auto_power_down_last_tick &&
                (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.auto_power_down_last_tick))
            {
                if ((!dpm_port_dead_battery_get()) &&
                    ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.auto_power_down_last_tick) >= SYS_POWER_BANK_IDLE_DETECT_DURATION))
                {
                    sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
                }

                if ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.auto_power_down_last_tick) >= SYS_POWER_BANK_AUTO_POWER_DOWN_DELAY)
                {
                    g_sys_pd_info.usba_no_current_flow_last_flag = FALSE;
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Auto off\n");
#endif /* CLI_ENABLED */
                    // flash 3 times
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
    				sys_capacity_set(sys_bat_capacity_get());
                    sys_capacity_reset_flag_set(FALSE);
    		        sys_capacity_para_save();
#endif
                    if (dpm_port_dead_battery_get())
                    {
                        dpm_port_dead_battery_set(FALSE);
                        sys_bat_state_set(SYS_BAT_STATE_IDLE);
                    }

                    sys_pd_display_flash_manually(3,FALSE);
                    //sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
                    //sys_cmd_port_disable_set(TRUE);
                    // disable USB-A
                    //disable 8812 pstop
#if 0
                    sys_gpio_pmic_pstop_set(FALSE);
                    // 8812 ad_start set 1
                    SYS_BAT_REG_FIELD_SET(CTRL3_SET_REG,AD_START,FALSE);
                    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
                    SYS_BAT_REG_SET(MASK_REG,0x8e);

                    sys_gpio_usba_c2_enble_set(FALSE);
                    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
#endif
                    dpm_cc_state_release();
                    dpm_cc_state_init();
                    dpm_rp_rd_clear();
                    rtc_delay_us(1000000UL);
                    DRV_INTR_GLOBAL_DISABLE();
                    sys_gpio_power_on_set(OFF);
                    sys_tick_t power_off = now();
                    while(1)
                    {
    					if((now()-power_off)>SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
    					{
    						break;
    					}
    				}
                    drv_chip_reset();
                }
            }
        }
        else {
            g_sys_pd_info.auto_power_down_last_tick = 0;
            //dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        }
    }
}
#if SYS_OVERTEMP_DECTION_ENABLED
/*温度保护函数*/
void sys_ntc_temp_protection()
{
    if (!g_sys_pd_info.ntc_test_flag)
    {
        //g_sys_pd_info.ntc_volt = drv_adc_read_multi_avg(SYS_NTC_ADC_ID,5) * drv_flash_trim_ref_volt_get() * 10 / ADC_REF_DIVISOR;
        g_sys_pd_info.ntc_volt = sys_bat_adin_val_get() * 10;
    }
    g_sys_pd_info.p60c_otp_pre_flag = g_sys_pd_info.p60c_otp_flag;
    g_sys_pd_info.p55c_otp_pre_flag = g_sys_pd_info.p55c_otp_flag;
    g_sys_pd_info.p45c_otp_pre_flag = g_sys_pd_info.p45c_otp_flag;
    g_sys_pd_info.p40c_otp_pre_flag = g_sys_pd_info.p40c_otp_flag;
    g_sys_pd_info.p0c_otp_pre_flag = g_sys_pd_info.p0c_otp_flag;
    g_sys_pd_info.m10c_otp_pre_flag = g_sys_pd_info.m10c_otp_flag;
    if (g_sys_pd_info.ntc_volt < DPM_TEMP_INVALID_VOLT)
    {
        /** Temperature greater than 60C, disable charge and discharge */
        if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P60C_VOLT)
        {
            if (!g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = TRUE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTP 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
            }

#if SYS_QUICK_CHARGE_ENABLED
            if (usbpd_cfg_port_quick_charge_en_get())
            {
                dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
            }
#endif
            if (dpm_vbus_source_en_get())
            {
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pmic_pstop_set(FALSE);
                sys_gpio_vbus_en_set(FALSE);
                usbpd_cfg_port_source_ocp_en_set(FALSE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            }
            //sys_gpio_usba1_power_on_set(FALSE);
            //sys_gpio_usba2_power_on_set(FALSE);
            sys_gpio_usba_c2_enble_set(FALSE);
            //sys_gpio_pd_qc_led_off();
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P55C_VOLT) /** Temperature greater than 55C, disable charge */
        {
            if (!g_sys_pd_info.p55c_otp_flag)
            {
                g_sys_pd_info.p55c_otp_flag = TRUE;
#if CLI_ENABLED
			    if (sys_cfg_dbg_get()) printf("DCHG:OTP 60-55C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P45C_VOLT) /** Temperature greater than 55C, disable charge */
        {
            if (!g_sys_pd_info.p45c_otp_flag)
            {
                g_sys_pd_info.p45c_otp_flag = TRUE;
#if CLI_ENABLED
			    if (sys_cfg_dbg_get()) printf("DCHG:OTP 45-55C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P40C_VOLT) /** Temperature greater than 40C, halve charge power */
        {
            if (g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (g_sys_pd_info.m10c_otp_flag)
            {
                g_sys_pd_info.m10c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR -10C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (!g_sys_pd_info.p40c_otp_flag)
            {
                g_sys_pd_info.p40c_otp_flag = TRUE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTP 45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                    sys_bat_rated_charging_current_set((sys_bat_rated_charging_current_get() >> 1));
                    sys_bat_ibus_set(sys_bat_rated_charging_current_get());
                }
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_0C_VOLT)
        {
            if (g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (g_sys_pd_info.m10c_otp_flag)
            {
                g_sys_pd_info.m10c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR -10C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (g_sys_pd_info.p40c_otp_flag)
            {
                g_sys_pd_info.p40c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (g_sys_pd_info.p45c_otp_flag)
            {
                g_sys_pd_info.p45c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (g_sys_pd_info.p0c_otp_flag)
            {
                g_sys_pd_info.p0c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) &&
                (g_sys_pd_info.charging_current_saved))
            {
                sys_bat_rated_charging_current_set(g_sys_pd_info.charging_current_saved);
                //sys_bat_ibus_set(g_sys_pd_info.charging_current_saved);
                sys_bat_ibus_set(500);
                g_sys_pd_info.charging_current_saved = 0;
                sys_bat_charging_current_reach_peak_flag_set(FALSE);
                dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
                dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_OTP_MASK;
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_M5C_VOLT)
        {
            if (!g_sys_pd_info.p0c_otp_flag)
            {
                g_sys_pd_info.p0c_otp_flag = TRUE;
#if CLI_ENABLED
			    if (sys_cfg_dbg_get()) printf("CHG:OTP -5-0C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
            }
        }
        else if (g_sys_pd_info.ntc_volt > DPM_TEMP_M5C_VOLT)
        {
            if (!g_sys_pd_info.m10c_otp_flag)
            {
                g_sys_pd_info.m10c_otp_flag = TRUE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTP -5C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
            }

#if SYS_QUICK_CHARGE_ENABLED
            if (usbpd_cfg_port_quick_charge_en_get())
            {
                dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
            }
#endif
            if (dpm_vbus_source_en_get())
            {
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pmic_pstop_set(FALSE);
                sys_gpio_vbus_en_set(FALSE);
                usbpd_cfg_port_source_ocp_en_set(FALSE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            }
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
            //sys_gpio_usba1_power_on_set(FALSE);
            //sys_gpio_usba2_power_on_set(FALSE);
            sys_gpio_usba_c2_enble_set(FALSE);
            //sys_gpio_pd_qc_led_off();
        }

        // retore
        if ((((g_sys_pd_info.p60c_otp_pre_flag)&& (!g_sys_pd_info.p60c_otp_flag)) ||
            ((g_sys_pd_info.m10c_otp_pre_flag)&& (!g_sys_pd_info.m10c_otp_flag))) &&
            (!dpm_port_dead_battery_get()))
        {
            //sys_usba_restore();
            sys_gpio_pmic_pstop_set(TRUE);
            sys_gpio_vbus_en_set(TRUE);
            usbpd_cfg_port_source_ocp_en_set(TRUE);
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_OTP_MASK;

            if ((dpm_cable_detect_done_get()) &&
                (dpm_current_pwr_mode_get()))
            {
                if (pe_pd_connected_get())
                {
                    if(!dpm_port_epr_mode_get())
                    {
                        dpm_hard_reset_req_set(TRUE);
                        pe_state_machine();
                    }
                    else
                    {
                        pe_error_recovery_directed_set(TRUE);
                    }
                }
                else {
                    dpm_vbus_source_en_set(TRUE);
#if SYS_QUICK_CHARGE_ENABLED
                    if (usbpd_cfg_port_quick_charge_en_get())
                    {
                        dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
                    }
#endif
                }
            }
        }
    }
}
#endif
/*USBC电压补偿函数*/
void usbc_volt_adjust()
{
    if (dpm_cable_detect_done_get())
    {
        if (POWER_MODE_SINK == dpm_current_pwr_mode_get() &&
            (!pe_prs_in_prog_get()))
        {
            // need to draw current flow smoothly
            sys_bat_charge_current_update();
        }
#if SYS_VOLTAGE_COMPENSATION_ENABLED
        else if (dpm_current_pwr_mode_get() &&
            (!dpm_port_dead_battery_get()) &&
            pe_pd_connected_get() &&
            (!pe_prs_in_prog_get()) &&
            (dpm_src_obj_pos_get() > 0) &&
            (POWER_SUPPLY_TYPE_FIXED == usbpd_cfg_port_src_pwr_supply_type_get((dpm_src_obj_pos_get()-1))))
        {
            u32_t vbus_cfg = usbpd_cfg_port_src_fixed_pwr_volt_cap_get((dpm_src_obj_pos_get()-1))*VOLTAGE_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
            u32_t ibus_cfg = usbpd_cfg_port_src_fixed_pwr_curr_cap_get((dpm_src_obj_pos_get()-1))*CURRENT_DIV ;

            if (ibus_cfg >= CURRENT_3000mA)
            {
                ibus_cfg = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO * ibus_cfg + SYS_POWER_BANK_CURRENT_COMPENSATION;

            }
            else {
                ibus_cfg = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * ibus_cfg + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
            }

            if ((g_sys_pd_info.ibus_current >= 4000)&&(!g_sys_pd_info.usbc_curr_4a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+500U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED
                if (sys_cfg_dbg_get()) printf("usbc_curr_4a_vol_chang_flag\n");
#endif
            }
            else if ((g_sys_pd_info.ibus_current >= 3200)&&(g_sys_pd_info.ibus_current < 4000)&&(!g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+300U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED
               if (sys_cfg_dbg_get()) printf("usbc_curr_3.2a_vol_chang_flag\n");
#endif
            }
            else if ((g_sys_pd_info.ibus_current >= 2400)&&(g_sys_pd_info.ibus_current < 3200)&&(!g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+250U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED
               if (sys_cfg_dbg_get()) printf("usbc_curr2.4a_vol_chang_flag\n");
#endif
            }
            else if ((g_sys_pd_info.ibus_current >= 1600)&&(g_sys_pd_info.ibus_current < 2400)&&(!g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+150U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED
                if (sys_cfg_dbg_get()) printf("usbc_curr1.6a_vol_chang_flag\n");
#endif

            }
            else if ((g_sys_pd_info.ibus_current >= 800)&&(g_sys_pd_info.ibus_current < 1600) &&(!g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+100U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED
                if (sys_cfg_dbg_get())  printf("usbc_curr0.8a_vol_chang_flag\n");
#endif
            }
            else
            {
                if((g_sys_pd_info.ibus_current < 800)&&(!g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag))
                {
                    sys_bat_discharge_vbus_ibus_set(vbus_cfg,ibus_cfg, OUT_DIR);
                    g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = TRUE;
#if CLI_ENABLED
                    if (sys_cfg_dbg_get()) printf("usbc_curr<0.8a_vol_chang_flag\n");
#endif
                }
			}
        }
#endif /* SYS_VOLTAGE_COMPENSATION_ENABLED */
    }
}
/*电池低电量状态退出检测函数*/
void dead_battery_exit_checkout()
{
    if (dpm_port_dead_battery_get())
    {
        if (!pe_prs_in_prog_get())
        {
            /* Enable charging in non-PD mode, and clear dead battery flag */
            if ((((PE_SNK_READY == pe_state_get()) &&
                (1 <= dpm_rx_src_cap_num_get()) &&
                (dpm_rx_src_cap_max_power_get() >= DEFAULT_MIN_PD_POWER)) ||
                ((DPM_CC_ATTACHED_SNK == dpm_cc_state_get()) &&
                ((g_pe_info.hard_reset_cnt > N_HARD_RESET_CNT)))))
            {
                if ((PE_SNK_READY == pe_state_get()) && (1 == dpm_rx_src_cap_num_get()) &&
                    (((UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(CFG_VOLTAGE_5V_IDX))->dual_role_pwr) &&
                    (((UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(CFG_VOLTAGE_5V_IDX))->usb_comm_cap))
                {
#if CLI_ENABLED
            		if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2) printf("NC\n");
#endif /* CLI_ENABLED */
                }
                else {
#if CLI_ENABLED
    		        if (sys_cfg_dbg_get()) printf("Dead exit:%umV\n", sys_bat_current_vbat_val_get());
#endif /* CLI_ENABLED */
                    dpm_port_dead_battery_set(FALSE);
                    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_LCP_MASK;
                    //sys_usba_restore();
                    if (sys_pd_led_state_get() == SYS_PD_LED_STATE_FLASH_FAST)
                    {
                        sys_bat_state_set(SYS_BAT_STATE_CHARGE);
                        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                    }
                }
            }
        }
    }
}
/*电池充满检测函数*/
void battery_charging_isfull()
{
#if SYS_SMG_DISPLAY_ENABLED  /* modified by James Gan - 2019-11-25 */
    if ((dpm_cable_detect_done_get()) &&
        (sys_bat_charging_flag_get()) &&
        (!dpm_current_pwr_mode_get()) &&
        (sys_bat_capacity_get() >= 100) &&
        (sys_bat_avg_ibat_val_get() < 300) &&
        (sys_bat_charging_start_tick_get() > 0) &&
        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_start_tick_get()) &&
        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_start_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME) &&
        (!sys_bat_charging_full_tick_get()))
    {
        sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick);
    }
#else
    if ((dpm_cable_detect_done_get()) &&
        (sys_bat_charging_flag_get()) &&
        (!dpm_current_pwr_mode_get()) &&
        (sys_bat_capacity_get() >= 90) &&
        (sys_bat_avg_ibat_val_get() < 400) &&
        (sys_bat_charging_start_tick_get() > 0) &&
        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_start_tick_get()) &&
        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_start_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME) &&
        (!sys_bat_charging_full_tick_get()))
    {
        sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick);
    }
#endif /* #if SYS_SMG_DISPLAY_ENABLED */
}
/*小电流模式处理函数*/
void sys_small_current_mode()
{
    if (g_sys_pd_info.prevent_auto_poweroff)
    {
        if (g_sys_pd_info.prevent_auto_poweroff_last_state != g_sys_pd_info.prevent_auto_poweroff)
        {
            g_sys_pd_info.prevent_auto_poweroff_last_state = g_sys_pd_info.prevent_auto_poweroff;

            //sys_gpio_usba_dc_enble_set(TRUE);
            //sys_gpio_usba1_volt_check_en(TRUE);
            //sys_gpio_usba2_volt_check_en(TRUE);
            //sys_gpio_usba_c2_enble_set(TRUE);

#if CLI_ENABLED
            if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("DCHG LI\n");
#endif /* CLI_ENABLED */
            if (!g_sys_pd_info.usba_ocp_flag)
            {
                sys_gpio_usba_c2_enble_set(TRUE);
#if 0
                if (!sys_gpio_usba2_power_on_get())
                {
                    sys_gpio_usba2_power_on_set(TRUE);
                    g_sys_pd_info.usba_no_current_flow_flag = FALSE;
                    g_sys_pd_info.usba2_disconnected_tick = 0;
                    g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
                    if (sys_cfg_dbg_get()) printf("A2 On\n");
#endif /* CLI_ENABLED */
                }
                if (!sys_gpio_usba1_power_on_get())
                {
                    sys_gpio_usba1_power_on_set(TRUE);
                    g_sys_pd_info.usba_no_current_flow_flag = FALSE;
                    g_sys_pd_info.usba1_disconnected_tick = 0;
                    g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
                    if (sys_cfg_dbg_get()) printf("A1 On\n");
#endif /* CLI_ENABLED */
                }
#endif
            }
        }
    }
    else {
        g_sys_pd_info.prevent_auto_poweroff_last_state = FALSE;
    }
}

#if SYS_USBA_ENABLED
/*USBA插入检测函数*/
void sys_usba_indet_detect()
{
    if ((!g_sys_pd_info.usba_ocp_flag) && (!(g_sys_pd_info.prevent_auto_poweroff)))
    {
#if 1
       g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_current_flag;
       g_sys_pd_info.usba1_indet_current_flag = sys_gpio_usba1_insert_detect_get();

       if (g_sys_pd_info.usba1_indet_current_flag)
       {
           if ((g_sys_pd_info.usba1_indet_current_flag != g_sys_pd_info.usba1_indet_pre_flag) &&
               (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba1_disconnected_tick > 4))
           {
               g_sys_pd_info.usba1_indet_flag = g_sys_pd_info.usba1_indet_current_flag;
               sys_gpio_usba1_insert_detect_clear();

               g_sys_pd_info.usba_no_current_flow_flag = FALSE;
               g_sys_pd_info.usba1_disconnected_tick = 0;
               g_sys_pd_info.usba_no_current_start_tick = 0;
               sys_gpio_usba_dc_enble_set(TRUE);
               sys_gpio_usba2_qc_enble_set(FALSE);
               sys_gpio_usba1_power_on_set(TRUE);
               sys_gpio_usba1_volt_check_en(TRUE);
#if CLI_ENABLED
               if (sys_cfg_dbg_get()) drv_uart_puts("A1 indet");
#endif /* CLI_ENABLED */
           }
       }
#endif
#if 1
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_current_flag;
        g_sys_pd_info.usba2_indet_current_flag = sys_gpio_usba2_insert_detect_get();

        if (g_sys_pd_info.usba2_indet_current_flag)
        {
            if ((g_sys_pd_info.usba2_indet_current_flag != g_sys_pd_info.usba2_indet_pre_flag) &&
                (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba2_disconnected_tick > 4))
            {
                g_sys_pd_info.usba2_indet_flag = g_sys_pd_info.usba2_indet_current_flag;
                sys_gpio_usba2_insert_detect_clear();
                sys_gpio_usba_dc_enble_set(TRUE);

                sys_gpio_usba2_power_on_set(TRUE);
                sys_gpio_usba2_volt_check_en(TRUE);

                g_sys_pd_info.usba_no_current_flow_flag = FALSE;
                g_sys_pd_info.usba2_disconnected_tick = 0;
                g_sys_pd_info.usba_no_current_start_tick = 0;

                if(g_sys_pd_info.usba1_indet_flag)
                {
                    sys_gpio_usba2_qc_enble_set(FALSE);
                }
                else
                {
                    sys_gpio_usba2_qc_enble_set(TRUE);
                }
#if CLI_ENABLED
                if (sys_cfg_dbg_get()) drv_uart_puts("A2 indet");
#endif /* CLI_ENABLED */
            }
        }
#endif
    }
}
/*USBA退载检测函数*/
void sys_usba_unload()
{
    if ((!g_sys_pd_info.usba_ocp_flag) && (!(g_sys_pd_info.prevent_auto_poweroff)))
    {
#if 0
        if ((g_sys_pd_info.usba2_indet_flag||g_sys_pd_info.usba1_indet_flag) &&
            (g_sys_pd_info.usba_no_current_flow_flag) &&
            (g_sys_pd_info.usba_no_current_start_tick) &&
            (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba_no_current_start_tick > SYS_USBA_CONNECTION_TIMEOUT))
        {
            g_sys_pd_info.usba2_indet_flag = FALSE;
            g_sys_pd_info.usba1_indet_flag = FALSE;

            sys_gpio_usba_dc_enble_set(FALSE);
            sys_gpio_usba2_qc_enble_set(FALSE);
            sys_gpio_usba1_power_on_set(FALSE);
            sys_gpio_usba2_power_on_set(FALSE);
            sys_gpio_usba1_volt_check_en(FALSE);
            sys_gpio_usba2_volt_check_en(FALSE);
            g_sys_pd_info.usba2_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
            g_sys_pd_info.usba1_disconnected_tick = g_sys_pd_info.continuous_timer_tick;

#if CLI_ENABLED
            if (sys_cfg_dbg_get()) drv_uart_puts("No Current A2 Off, A1 QC On");
#endif /* CLI_ENABLED */
        }
#endif
     if(sys_gpio_usba_c2_enble_get()&&(((g_sys_pd_info.usba_no_current_flow_flag)&&
        (g_sys_pd_info.usba_no_current_start_tick)&&(g_sys_pd_info.usbc2_no_current_flow_flag)
        &&(g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba_no_current_start_tick > SYS_USBA_CONNECTION_TIMEOUT))||
        (g_sys_pd_info.usbc2_no_current_flow_flag && g_sys_pd_info.usbc2_no_current_start_tick &&(g_sys_pd_info.usba_no_current_flow_flag)&&
        (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usbc2_no_current_start_tick > SYS_USBA_CONNECTION_TIMEOUT))))
        {
            sys_gpio_usba_c2_enble_set(FALSE);
            g_sys_pd_info.usba_no_current_start_tick = 0;
            g_sys_pd_info.usbc2_no_current_start_tick = 0;

#if CLI_ENABLED
            if (sys_cfg_dbg_get())
            {
                printf("a&c2 disable!!!\n");
                printf("usba_no_current_start_tick=%d\n",g_sys_pd_info.usba_no_current_start_tick);
                printf("usbc2_no_current_start_tick=%d\n",g_sys_pd_info.usbc2_no_current_start_tick);
            }
#endif
        }
    }
}

/*USBA过流保护函数*/
void sys_usba_ocp_protection()
{
#if 0
    if (((sys_gpio_usba1_power_on_get()) &&
        (((g_sys_pd_info.usba_vbus_val <= VSAFE_5V_DISCONNECT)&&
        (sys_usba_ibus_get()>1000))||
        (g_sys_pd_info.usba_vbus_val * sys_usba_ibus_get() >= 22000000UL)))
        ||(sys_gpio_usba2_power_on_get()&&(((g_sys_pd_info.usba2_vbus_val <= VSAFE_5V_DISCONNECT)&&
        (sys_usba_ibus_get()>1000))
        ||(g_sys_pd_info.usba2_vbus_val * sys_usba_ibus_get() >= 22000000UL))))

    {
        g_sys_pd_info.usba_ocp_flag = TRUE;
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(FALSE);
        sys_gpio_usba2_power_on_set(FALSE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        g_sys_pd_info.usba1_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
        g_sys_pd_info.usba2_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
#if CLI_ENABLED
		if (sys_cfg_dbg_get()) printf("USB-A OCP, Power Off\n");
#endif /* CLI_ENABLED */
    }
#endif
}
#endif
/*检测USBC在没有连接的情况下是否有大于6V电压*/
void sys_usbc_vbus_check()
{

    if ((!usbpd_cfg_capture_mode_get()) &&
        (usbpd_cfg_port_vbus_check_get()) &&
        (!dpm_cable_detect_done_get()) &&
        (g_sys_pd_info.vbus_current > 6000U) &&
        ((u32_t)(now() - dpm_cc_connection_changed_time_get()) > 600000UL) &&
        (!pe_error_recovery_directed_get()))
    {
#if USBPD_DEBUG_ENABLED
		if (usbpd_cfg_dbg_get()) drv_uart_puts("VBUS > 6V, No connection");
#endif /* CLI_ENABLED */
        pe_error_recovery_directed_set(TRUE);
    }

}
/*系统关机函数*/
void sys_shutdown(void)
{
    if (dpm_port_dead_battery_get())
    {
        dpm_port_dead_battery_set(FALSE);
        sys_bat_state_set(SYS_BAT_STATE_IDLE);
    }

    dpm_cc_state_release();
    dpm_cc_state_init();
    dpm_rp_rd_clear();
    rtc_delay_us(1000000UL);
    DRV_INTR_GLOBAL_DISABLE();
    sys_gpio_power_on_set(OFF);

    sys_tick_t start = now();
    while (((u32_t)(now() - start) < SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL));
}
/*mcu的充放电控制处理函数*/
void sys_mcu_charge_discharge_ctrl()
{
    *(u8_t *)(&g_sys_pd_info.mcu_state_pre) = *(u8_t *)(&g_sys_pd_info.mcu_state);
    *(u8_t *)(&g_sys_pd_info.mcu_state)= dpm_ex_pw_ctrl_get();

    if ((dpm_port_state_get()== DPM_PORT_STATE_CHARGE) &&
        (g_sys_pd_info.mcu_state.charge_en != g_sys_pd_info.mcu_state_pre.charge_en))
    {
#if USBPD_DEBUG_ENABLED
        if (usbpd_cfg_dbg_get())
        {
            printf("charge mcu_ctrl_state=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state));
            printf("charge mcu_ctrl_state_pre=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state_pre));
        }
#endif /* CLI_ENABLED */
        if (g_sys_pd_info.mcu_state.charge_en)
        {
            if (g_sys_pd_info.charging_current_saved)
            {
                sys_bat_rated_charging_current_set(g_sys_pd_info.charging_current_saved);
                sys_bat_ibus_set(g_sys_pd_info.charging_current_saved);
                g_sys_pd_info.charging_current_saved = 0;
                sys_bat_charging_current_reach_peak_flag_set(FALSE);
            }

            if (!sys_gpio_pmic_pstop_get())
            {
                sys_gpio_pmic_pstop_set(TRUE);
            }

            if (!sys_gpio_vbus_en_get())
            {
                sys_gpio_vbus_en_set(TRUE);
            }
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
        }
        else
        {
            if (!g_sys_pd_info.charging_current_saved)
            {
                g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
            }

            sys_bat_rated_charging_current_set(0);
            sys_bat_ibus_set(SYS_BAT_SC8815_CURRENT_MIN);
            sys_gpio_pmic_pstop_set(FALSE);
            sys_bat_charging_current_reach_peak_flag_set(TRUE);
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
        }
    }
    if ((dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE) &&
        (g_sys_pd_info.mcu_state.discharge_en != g_sys_pd_info.mcu_state_pre.discharge_en))
    {
#if USBPD_DEBUG_ENABLED
        if (usbpd_cfg_dbg_get())
        {
            printf("discharge mcu_ctrl_state=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state));
            printf("discharge mcu_ctrl_state_pre=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state_pre));
        }
#endif /* CLI_ENABLED */

        if ((g_sys_pd_info.mcu_state.discharge_en) &&
            (!dpm_port_dead_battery_get()) &&
            (!dpm_source_ocp_flag_get()))
        {
            pe_error_recovery_directed_set(TRUE);
        }
        else
        {
            if(dpm_vbus_source_en_get())
            {
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pmic_pstop_set(FALSE);
                sys_gpio_vbus_en_set(FALSE);
                //usbpd_cfg_port_source_ocp_en_set(FALSE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            }

#if SYS_QUICK_CHARGE_ENABLED
            if (usbpd_cfg_port_quick_charge_en_get())
            {
                dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
            }
#endif
        }
    }

    if ((!dpm_cable_detect_done_get())&&
        (g_sys_pd_info.mcu_state.power_off))
    {
        sys_shutdown();
    }
}
/*ibus过流检测*/
bool_t sys_pd_ibus_over_check()
{
    if ((dpm_src_obj_pos_get() <= 1) &&
        (!source_in_pwr_negotiation()) &&
        ((g_sys_pd_info.ibus_current >= IBUS_VSAFE5V_OVER_MAX) || 
        ((BC_QC_SRC_CONNECTED <= bc_qc_state_get(&g_usbc_qc_info)) && (g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current >= 23000000UL))))
    {
#if USBPD_DEBUG_ENABLED
        if (usbpd_cfg_dbg_get())  printf("\nOCP,N=%u,R=%u\n",CURRENT_3000mA,g_sys_pd_info.ibus_current);
#endif /* USBPD_DEBUG_ENABLED */
        return TRUE;
    }
    else if ((!dpm_vbus_at_vsafe5v_get()) &&
        (!source_in_pwr_negotiation()) &&
        (dpm_src_obj_pos_get() > 1))
    {
        u32_t current = g_sys_pd_info.rated_ibus;

        if (current >= CURRENT_3000mA)
        {
            current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO * current + SYS_POWER_BANK_CURRENT_COMPENSATION;
        }
        else {
            current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * current + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
        }

        if ((POWER_SUPPLY_TYPE_FIXED == usbpd_cfg_port_src_pwr_supply_type_get((dpm_src_obj_pos_get()-1))) &&
            (g_sys_pd_info.ibus_current >= current))
        {
#if USBPD_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get())  printf("\nOCP FIXED,N=%u,R=%u\n",current,g_sys_pd_info.ibus_current);
#endif /* USBPD_DEBUG_ENABLED */
            return TRUE;
        }
        else if ((POWER_SUPPLY_TYPE_PPS == usbpd_cfg_port_src_pwr_supply_type_get((dpm_src_obj_pos_get()-1))) &&
            (g_sys_pd_info.ibus_current >= current))
        {
#if USBPD_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get())  printf("\nOCP PPS,N=%u,R=%u\n",current,g_sys_pd_info.ibus_current);
#endif /* USBPD_DEBUG_ENABLED */
            return TRUE;
        }
        else {
            return FALSE;
        }
    }
    else {
        return FALSE;
    }
}
/*pd epr mode 进入检测函数*/
void sys_pd_check_epr()
{
    // sink request process
    if (PE_SNK_READY == pe_state_get())
    {
        int cap_pos = dpm_src_obj_pos_get();
        u32_t volt, current;
        UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_src_cap_fixed = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
        if (POWER_SUPPLY_TYPE_BATTERY == p_src_cap_fixed->supply_type)
        {
            UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *p_src_cap_battery = (UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
            volt = p_src_cap_battery->max_volt * VOLTAGE_DIV;
            current = (u32_t)(p_src_cap_battery->max_allow_pwr) * POWER_DIV * 1000 / volt;
        }
        else if (POWER_SUPPLY_TYPE_VARIABLE == p_src_cap_fixed->supply_type)
        {
            UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *p_src_cap_vari = (UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
            volt = p_src_cap_vari->max_volt * VOLTAGE_DIV;
            current = p_src_cap_vari->max_curr * CURRENT_DIV;
        }
        else {
            volt = p_src_cap_fixed->volt * VOLTAGE_DIV;
            current = p_src_cap_fixed->max_curr * CURRENT_DIV;
        }

        if (usbpd_cfg_port_epr_mode_en_get()&& (!dpm_port_epr_mode_get())&&
            (volt == VOLTAGE_20V)&&(current >= 4000)&&(!dpm_rx_epr_fail_msg_get()))
        {
            UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_src_cap_fixed_5v = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(0);
            if ((p_src_cap_fixed_5v->epr == TRUE)&&(!dpm_snk_epr_mode_req_get()))
            {
                dpm_snk_epr_mode_req_set(TRUE);
                //g_sys_pd_info.snk_request_is_need = FALSE;
                sys_pd_cfg_snk_epr_operating_power_profile_set(SNK_POWER_REQUIRE_140W);
            }
        }
    }
}


bool_t sys_new_power_level_req()
{
    UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_cap_fixed;
    UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *p_cap_vari;
    UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *p_cap_battery;
    u32_t voltage, min_voltage, current_volt;
    u32_t current;
    int src_obj = dpm_src_obj_pos_get();

    if (usbpd_cfg_cable_plug_get() || (dpm_current_pwr_mode_get()) ||
        (!dpm_cable_detect_done_get()))
        return(FALSE);


    if (src_obj == dpm_rx_src_cap_num_get())
    {
        dpm_src_obj_pos_set(1);
        src_obj = 0;
    }
    else {
        dpm_src_obj_pos_set(src_obj+1);
    }


    usbpd_cfg_port_snk_pwr_prof_set(SNK_POWER_PROFILE_CUSTOM);
    p_cap_fixed = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(src_obj);
    while (p_cap_fixed->volt == 0)
    {
        src_obj = dpm_src_obj_pos_get();
        if (src_obj == dpm_rx_src_cap_num_get())
        {
            dpm_src_obj_pos_set(1);
            src_obj = 0;
        }
        else {
            dpm_src_obj_pos_set(src_obj+1);
        }
        p_cap_fixed = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(src_obj);
    }

    if (POWER_SUPPLY_TYPE_BATTERY == p_cap_fixed->supply_type)
    {
        p_cap_battery = (UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *)dpm_rx_src_cap_object_get(src_obj);
        voltage = (MAX_VOLT_GET(p_cap_battery) + MIN_VOLT_GET(p_cap_battery))/2;
        current = (u32_t)(MAX_ALLOW_PWR_GET(p_cap_battery)) * POWER_DIV / (voltage * VOLTAGE_DIV) * 1000 / CURRENT_DIV;
        if (dpm_port_epr_mode_get() == TRUE)
        {
            usbpd_cfg_port_snk_epr_pwr_volt_set(voltage);
            usbpd_cfg_port_snk_epr_pwr_curr_set(current);
            usbpd_cfg_port_snk_epr_pwr_max_curr_set(current);
        }
        else
        {
            usbpd_cfg_port_snk_pwr_volt_set(voltage);
            usbpd_cfg_port_snk_pwr_curr_set(current);
            usbpd_cfg_port_snk_pwr_max_curr_set(current);
        }
    }
    else if (POWER_SUPPLY_TYPE_VARIABLE == p_cap_fixed->supply_type)
    {
        p_cap_vari = (UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *)dpm_rx_src_cap_object_get(src_obj);
        voltage = (MAX_VOLT_GET(p_cap_vari) + MIN_VOLT_GET(p_cap_vari))/2;
        if (dpm_port_epr_mode_get() == TRUE)
        {
            usbpd_cfg_port_snk_epr_pwr_volt_set(voltage);
            usbpd_cfg_port_snk_epr_pwr_curr_set(MAX_CURR_GET(p_cap_fixed));
            usbpd_cfg_port_snk_epr_pwr_max_curr_set(MAX_CURR_GET(p_cap_fixed));
        }
        else
        {
            usbpd_cfg_port_snk_pwr_volt_set(voltage);
            usbpd_cfg_port_snk_pwr_curr_set(MAX_CURR_GET(p_cap_vari));
            usbpd_cfg_port_snk_pwr_max_curr_set(MAX_CURR_GET(p_cap_vari));
        }
    }
    else if (POWER_SUPPLY_TYPE_FIXED == p_cap_fixed->supply_type)
    {
        if (dpm_port_epr_mode_get() == TRUE)
        {
            if (VOLT_GET(p_cap_fixed)!= 0)
            {
                usbpd_cfg_port_snk_epr_pwr_volt_set(VOLT_GET(p_cap_fixed));
                usbpd_cfg_port_snk_epr_pwr_curr_set(MAX_CURR_GET(p_cap_fixed));
                usbpd_cfg_port_snk_epr_pwr_max_curr_set(MAX_CURR_GET(p_cap_fixed));
            }
        }
        else
        {
            usbpd_cfg_port_snk_pwr_volt_set(VOLT_GET(p_cap_fixed));
            usbpd_cfg_port_snk_pwr_curr_set(MAX_CURR_GET(p_cap_fixed));
            usbpd_cfg_port_snk_pwr_max_curr_set(MAX_CURR_GET(p_cap_fixed));
            if (src_obj >= 7)
            {
                if (usbpd_cfg_port_epr_mode_en_get()&& (!dpm_port_epr_mode_get())&&
                    (!dpm_rx_epr_fail_msg_get()))
                {
                    UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_src_cap_fixed_5v = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(0);
                    if ((p_src_cap_fixed_5v->epr == TRUE)&&(!dpm_snk_epr_mode_req_get()))
                    {
                        dpm_snk_epr_mode_req_set(TRUE);
                        sys_pd_cfg_snk_epr_operating_power_profile_set(SNK_POWER_REQUIRE_140W);
                        g_sys_pd_info.snk_request_is_need = FALSE;
#if USBPD_DEBUG_ENABLED
    		            if (usbpd_cfg_dbg_get()) drv_uart_puts("EPR req");
#endif /* CLI_ENABLED */
                    }
                }
            }
        }
    }
    else if (POWER_SUPPLY_TYPE_PPS == p_cap_fixed->supply_type)
    {
        if (src_obj >= 7)
        {
            if (usbpd_cfg_port_snk_epr_pwr_pps_en_get())
            {
                UPD_DATA_MSG_SOURCE_CAP_AVS_APDU_t *p_cap_avs = (UPD_DATA_MSG_SOURCE_CAP_AVS_APDU_t *)dpm_rx_src_cap_object_get(src_obj);
                voltage = p_cap_avs->max_volt * VOLTAGE_PPS_DIV;
                min_voltage = p_cap_avs->min_volt * VOLTAGE_PPS_DIV;
                current = p_cap_avs->pdp * 1000000 / voltage;
#if USBPD_DEBUG_ENABLED
                if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
                {
                    printf("avs-volt=%u,avs-curr=%u\n",voltage,current);
                }
#endif
                usbpd_cfg_port_pps_volt_step_set(100);
                if (VOLTAGE_28V <= voltage)
                {
                    usbpd_cfg_port_pps_volt_step_set(1500);
                }
                if (min_voltage < VOLTAGE_15V)
                    min_voltage = VOLTAGE_15V;
                usbpd_cfg_port_snk_epr_pwr_volt_set( min_voltage / VOLTAGE_DIV );
                usbpd_cfg_port_snk_epr_pwr_curr_set( current / CURRENT_DIV );
                usbpd_cfg_port_snk_epr_pwr_max_curr_set( current / CURRENT_DIV );
                dpm_pps_output_voltage_set(min_voltage);
                current_volt = dpm_vbus_volt_get();
                if (current_volt >= min_voltage)
                {
                    if (current_volt >= VOLTAGE_28V)
                    {
                        dpm_pps_output_voltage_set(VOLTAGE_28V);
                    }
                    else {
                        dpm_pps_output_voltage_set(current_volt);
                    }
                }
                usbpd_cfg_port_snk_epr_pwr_prof_set(SNK_POWER_PROFILE_PPS);
                usbpd_cfg_port_epr_operational_pdp_set(voltage * current / 1000000);
                //usbpd_cfg_port_maximum_pdp_set(usbpd_cfg_port_operational_pdp_get());
#if USBPD_DEBUG_ENABLED
                if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
                {
                    printf("epr_pwr_volt=%u\n",usbpd_cfg_port_snk_epr_pwr_volt_get());
                    printf("epr_pwr_curr=%u\n",usbpd_cfg_port_snk_epr_pwr_curr_get());
                }
#endif
            }
            else {
                if (1 == dpm_src_obj_pos_get())
                {
                    dpm_src_obj_pos_set(dpm_rx_src_cap_num_get());
                }
                else {
                    dpm_src_obj_pos_set(src_obj);
                }
                return FALSE;
            }
        }
        else
        {
            if (usbpd_cfg_port_snk_pwr_pps_en_get())
            {
                if (dpm_port_epr_mode_get())
                {
                    g_sys_pd_info.snk_request_pps_in_epr_mode = TRUE;
                    g_sys_pd_info.snk_request_pps_index_in_epr_mode = dpm_src_obj_pos_get();
                    dpm_epr_mode_exit_req_set(TRUE);
                    g_sys_pd_info.snk_request_epr_after_pps = TRUE;
                    g_sys_pd_info.snk_request_epr_index_after_pps = 7;
                    return TRUE;
                }
                else
                {
                    UPD_DATA_MSG_SOURCE_CAP_PPS_APDU_t *p_cap_pps = (UPD_DATA_MSG_SOURCE_CAP_PPS_APDU_t *)dpm_rx_src_cap_object_get(src_obj);
                    voltage = MAX_VOLT_GET(p_cap_pps) * VOLTAGE_PPS_DIV;
                    min_voltage = p_cap_pps->min_volt * VOLTAGE_PPS_DIV;
                    current = MAX_CURR_GET(p_cap_pps) * CURRENT_PPS_DIV;
                    usbpd_cfg_port_pps_volt_step_set(100);
                    if ((VOLTAGE_PPS_MAX_9V == voltage))
                    {
                        usbpd_cfg_port_pps_volt_step_set(400);
                    }
                    else if ((VOLTAGE_PPS_MAX_15V == voltage))
                    {
                        usbpd_cfg_port_pps_volt_step_set(1000);
                    }
                    else if ((VOLTAGE_PPS_MAX_20V == voltage))
                    {
                        usbpd_cfg_port_pps_volt_step_set(1500);
                    }
                    if (min_voltage < VOLTAGE_5V)
                        min_voltage = VOLTAGE_5V;
                    usbpd_cfg_port_snk_pwr_volt_set( min_voltage / VOLTAGE_DIV );
                    usbpd_cfg_port_snk_pwr_curr_set( current / CURRENT_DIV );
                    usbpd_cfg_port_snk_pwr_max_curr_set( current / CURRENT_DIV );
                    dpm_pps_output_voltage_set(min_voltage);
                    current_volt = dpm_vbus_volt_get();
                    if (current_volt >= min_voltage)
                    {
                        if (current_volt >= VOLTAGE_PPS_MAX_20V)
                        {
                            dpm_pps_output_voltage_set(VOLTAGE_PPS_MAX_20V);
                        }
                        else {
                            dpm_pps_output_voltage_set(current_volt);
                        }
                    }
                    usbpd_cfg_port_snk_pwr_prof_set(SNK_POWER_PROFILE_PPS);
                    usbpd_cfg_port_operational_pdp_set(voltage * current / 1000000);
                    usbpd_cfg_port_maximum_pdp_set(usbpd_cfg_port_operational_pdp_get());
                }
            }
            else {
                if (1 == dpm_src_obj_pos_get())
                {
                    dpm_src_obj_pos_set(dpm_rx_src_cap_num_get());
                }
                else {
                    dpm_src_obj_pos_set(src_obj);
                }
                return FALSE;
            }

        }

    }
    if (VOLT_GET(p_cap_fixed)!= 0)
    {
        dpm_new_pwrlevel_req_set(TRUE);
    }

    return TRUE;
}


// 每100毫秒处理函数
void sys_continous_timer_hook0()
{
    g_sys_pd_info.continuous_timer_tick++;
    if (g_sys_pd_info.sys_initializing)
    {
#if SYS_LED_ENABLED
        sys_pd_init_display();
#else
        sys_init_config(); 
#endif /* #if SYS_LED_ENABLED */
    }
    else 
    {

        // 读取PMIC状态寄存器
        sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));

        // USBC 过压欠压保护
        sys_usbc_vbus_ovp_hanler();

        // 每隔500毫秒处理一次
        if ((g_sys_pd_info.continuous_timer_tick % 5) == 0)
        {
#if (SYS_LED_ENABLED||SYS_SMG_DISPLAY_ENABLED)
            // LED/数码管显示状态机处理
            sys_pd_display_state_machine();
            sys_pd_display_process();
#endif
        }
        if (0 == (g_sys_pd_info.continuous_timer_tick % 25))
        {
            sys_pd_power_policy_process(FALSE);
        }
        
        // 自动过流保护恢复
        // sys_usbc_ocp_restore();
    }
}

// VBAT 相关处理
void sys_continous_timer_hook1()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 电池电压更新
        sys_bat_vbat_update();

        // 电池低电量保护
        sys_deadbattery_protection();

        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {
            // 电池低电量退出检测
            dead_battery_exit_checkout();
        }

        // Check the capacity every 800 ms 
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x7))
        {
            battery_charging_isfull();
        }
    }
}

// VBUS/IBUS相关
void sys_continous_timer_hook2()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 每隔500毫秒处理一次
        if ((g_sys_pd_info.continuous_timer_tick % 5) == 0)
        {
            // 电压电流补偿
            usbc_volt_adjust();
        }

        // USBC VBUS无连接时电压检测
        sys_usbc_vbus_check();
        
        // 自动过流保护恢复
        // sys_usbc_ocp_restore();
    }
}

// IBAT，电量
void sys_continous_timer_hook3()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // get ibat value
        //g_sys_bat_info.current_ibat_val = sys_bat_ibat_val_get();

        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {
            // 确定电池充放电方向
            detect_current_direction();

            // 电池电量检测
            sys_bat_capacity_check();
        }
    }
}

// KEY
void sys_continous_timer_hook4()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {
            // 电源键事件处理
#if SYS_POWER_BANK_POWER_DOWN_DETECT
            powerkey_event_hander();   
#endif

#if SYS_POWER_BANK_AUTO_POWER_DOWN_EN
            // 自动关机检测
            chip_auto_power_off();
#endif
        }
    }
}

// USBA
void sys_continous_timer_hook5()
{
    if (!g_sys_pd_info.sys_initializing)
    {

#if SYS_USBA_ENABLED
        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {
            // USBA电流检测
            usba_current_check();
        }

        sys_usba_ocp_protection();
#endif

    }
}

// EPR检测
void sys_continous_timer_hook6()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {
            // PD3.1 EPR检测
            sys_pd_check_epr();
        }
    }
}

// 温度保护
void sys_continous_timer_hook7()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        /* 每隔400毫秒处理一次 */
        if ((g_sys_pd_info.continuous_timer_tick & 3) == 0)
        {
#if SYS_OVERTEMP_DECTION_ENABLED
            // 温度保护检测
            sys_ntc_temp_protection();
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
        }
    }
}

// PE状态检测
void sys_continous_timer_hook8()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 每隔200ms，事件处理
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
        {

        }
    }
}

// 其他检查
void sys_continous_timer_hook9()
{
    if (!g_sys_pd_info.sys_initializing)
    {
        // 800 ms处理一次
        if (0 == (g_sys_pd_info.continuous_timer_tick & 0x7))
        {
            // 电池充满检测
            battery_charging_isfull();
        }
        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
        {
#if (!SYS_UFCS_ENABLED)
            if ((g_sys_pd_info.continuous_timer_tick > 30) &&(drv_gpio_en_get(UART_RXD))&&((!dpm_cable_detect_done_get())||
                (sys_cfg_dbg_get())))    
            {
                sys_gpio_uart0_enable();
            }
#endif
        }
    }
}

typedef void (*sys_continous_timer_fptr)(void);

static const sys_continous_timer_fptr sys_continous_timer_hooks[SYS_CONTINUOUS_TIMER_HOOK_NUM] =
{
    sys_continous_timer_hook0,
    sys_continous_timer_hook1,
    sys_continous_timer_hook2,
    sys_continous_timer_hook3,
    sys_continous_timer_hook4,
    sys_continous_timer_hook5,
    sys_continous_timer_hook6,
    sys_continous_timer_hook7,
    sys_continous_timer_hook8,
    sys_continous_timer_hook9
};



/* PD协议栈空闲时系统回调函数，系统相关功能基本在这个函数实现 */
void sys_pd_idle_hook(u32_t arg)
{
    g_sys_pd_info.current_time = now();

    sys_tick_t start_time = now();

    if ((drv_timer_stopped(&(g_sys_pd_info.continuous_timer))) &&
        (!(drv_timer_expired(&(g_sys_pd_info.continuous_timer)))))
    {
        drv_timer_start(SYS_CONTINUOUS_TIMER_TIMEOUT, &(g_sys_pd_info.continuous_timer), NULL);
    }

#if SYS_POWER_KEY_ENABLED
    /*按键检测*/
    power_key_event_detect();
#endif
    /*MCU 中断处理函数*/
    if (sys_mcu_int_get())
    {
        drv_gpio_intr_en_set(sys_gpio_mcu_i2c_int, FALSE);
        sys_mcu_int_en_set(FALSE);
        drv_gpio_intr_en_set(sys_gpio_mcu_i2c_int, TRUE);
    }

    //handler QC state machine
#if SYS_QUICK_CHARGE_ENABLED
    if ((usbpd_cfg_port_quick_charge_en_get()) &&
        (!pe_pd_connected_get()) &&
        (!ufcs_pe_identified_get(UFCS_USBC_DEV)) &&
        (DPM_QC_DISABLED != dpm_qc_state_get(&g_usbc_qc_info)) &&
        ((g_pe_info.caps_cnt > 5) ||
         (dpm_port_state_get()==DPM_PORT_STATE_CHARGE) ||
         (usbpd_cfg_port_no_pd_mode_get())))
    {
        dpm_qc_state_machine(&g_usbc_qc_info);
    }
#else
#if SYS_UFCS_ENABLED
    //如果PD连接上，关闭UFCS协议
    if (pe_pd_connected_get())
    {
        // 关闭UFCS
        ufcs_pe_vbus_present_set(UFCS_USBC_DEV, FALSE);
        g_usbc_qc_info.src_dp_dm_mode = BC_SRC_DPDM_MODE_BC;
        g_usbc_qc_info.bc_qc_disable = TRUE;
        g_usbc_qc_info.src_dpdm_mode_set(BC_SRC_DPDM_MODE_BC);
    }
    if ((ufcs_pe_identified_get(UFCS_USBC_DEV)) &&
        (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE))
    {
        pe_state_set(PE_SRC_DISABLED);
        g_pe_info.caps_cnt = N_CAPS_COUNT;
    }

    if ((!pe_pd_connected_get()) &&
        (!ufcs_pe_identified_get(UFCS_USBC_DEV)) &&
        (BC_QC_DISABLED != bc_qc_state_get(&g_usbc_qc_info)) &&
        ((g_pe_info.caps_cnt > 5) ||
         (dpm_port_state_get()==DPM_PORT_STATE_CHARGE) ||
         (usbpd_cfg_port_no_pd_mode_get())))
    {
        bc_qc_state_machine(&g_usbc_qc_info);

        if ((dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE) &&
            (!ufcs_pe_vbus_present_get(UFCS_USBC_DEV)))
        {
            ufcs_pe_vbus_present_set(UFCS_USBC_DEV, TRUE);
            ufcs_pe_src_startup(UFCS_USBC_DEV);
        }
    }
#endif
#endif /* SYS_QUICK_CHARGE_ENABLED */

    // 系统事件处理，每隔10ms执行一次
    if (drv_timer_expired(&(g_sys_pd_info.continuous_timer)))
    {
        if (0 == (g_sys_pd_info.continuous_timer_fast_tick & 0x1))
        {
            // 每20毫秒更新电流值
            g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();
            // USBC 过流保护
            sys_usbc_ibus_ocp();
        }
        else {
            // 每20毫秒更新电压值
            g_sys_pd_info.vbus_current = sys_usbc_vbus_get();
        }

        sys_continous_timer_hooks[g_sys_pd_info.continuous_timer_fast_tick]();

        g_sys_pd_info.continuous_timer_fast_tick++;
        if (g_sys_pd_info.continuous_timer_fast_tick >= SYS_CONTINUOUS_TIMER_HOOK_NUM)
        {
            g_sys_pd_info.continuous_timer_fast_tick = 0;
        }

        // 重启定时器
        sys_tick_t current_time = now();
        u32_t duration = (u32_t)(current_time - start_time) / 1000;
        if (duration >= SYS_CONTINUOUS_TIMER_TIMEOUT)
        {
            // no need to restart timer and keep the timeout flag for next run
        }
        else {
            drv_timer_start(SYS_CONTINUOUS_TIMER_TIMEOUT-duration, &(g_sys_pd_info.continuous_timer), NULL);
        }
    }
}

void sys_pd_prl_msg_src_cap_hook(u8_t *p_msg, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_msg)
        return;

    if (dir == PRL_MSG_DIR_RX)
    {
        int cap_pos = dpm_src_obj_pos_get();
        u32_t volt, current;
        UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_src_cap_fixed = (UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
        if (POWER_SUPPLY_TYPE_BATTERY == p_src_cap_fixed->supply_type)
        {
            UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *p_src_cap_battery = (UPD_DATA_MSG_SOURCE_CAP_BATTERY_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
            volt = p_src_cap_battery->max_volt * VOLTAGE_DIV;
            current = (u32_t)(p_src_cap_battery->max_allow_pwr) * POWER_DIV * 1000 / volt;
        }
        else if (POWER_SUPPLY_TYPE_VARIABLE == p_src_cap_fixed->supply_type)
        {
            UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *p_src_cap_vari = (UPD_DATA_MSG_SOURCE_CAP_VARIABLE_SUPPLY_t *)dpm_rx_src_cap_object_get(cap_pos-1);
            volt = p_src_cap_vari->max_volt * VOLTAGE_DIV;
            current = p_src_cap_vari->max_curr * CURRENT_DIV;
        }
        else {
            volt = p_src_cap_fixed->volt * VOLTAGE_DIV;
            current = p_src_cap_fixed->max_curr * CURRENT_DIV;
        }
#if CLI_ENABLED
        if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("RX SRC CAP, POS:%u,V:%u,A:%u\n",cap_pos,volt,current);
#endif /* CLI_ENABLED */
        //current *= SYS_POWER_BANK_CHARGE_RATIO;
        g_sys_pd_info.rated_vbus = volt;
        g_sys_pd_info.rated_ibus = current;
    }
    else {
        if (dpm_cbl_plug_detected_get() && 
            (pe_prs_in_prog_get()) &&
            (VBUS_CURR_HANDLING_CAP_5A != dpm_rx_vdm_ack_cable_vbus_curr_cap_get()))
        {
            u16_t obj_num = 0;
            dpm_rx_vdm_ack_cable_vbus_curr_cap_set(VBUS_CURR_HANDLING_CAP_5A);
            for (int i = CFG_VOLTAGE_5V_IDX; i < usbpd_cfg_port_src_cap_num_get(); i++)
            {
                if ((POWER_SUPPLY_TYPE_FIXED == usbpd_cfg_port_src_pwr_supply_type_get(i)) && 
                    (usbpd_cfg_port_src_fixed_pwr_curr_cap_get(i)))
                {
                    volatile UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *p_cap_fixed;
                    p_cap_fixed = (volatile UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)&tx_data[UPD_MSG_HEAD_LEN+obj_num*UPD_MSG_DATA_OBJ_SIZE];
                    if ((CURRENT_3000mA / CURRENT_DIV) < usbpd_cfg_port_src_fixed_pwr_curr_cap_get(i))
                    {
                        p_cap_fixed->max_curr = usbpd_cfg_port_src_fixed_pwr_curr_cap_get(i);
                        dpm_tx_src_cap_gt_3a_flag_set(TRUE);
                    }
                    obj_num++;
                }
                else if (POWER_SUPPLY_TYPE_BATTERY == usbpd_cfg_port_src_pwr_supply_type_get(i))
                {
                    obj_num++;
                }
                else if (POWER_SUPPLY_TYPE_VARIABLE == usbpd_cfg_port_src_pwr_supply_type_get(i))
                {
                    obj_num++;
                }
                else if ((!dpm_pps_disabled_get()) && 
                    ((!dpm_req_spec_rev_get()) || (SPEC_REVISION_3_0 == dpm_req_spec_rev_get())) && 
                    (POWER_SUPPLY_TYPE_PPS == usbpd_cfg_port_src_pwr_supply_type_get(i)))
                {
                    volatile UPD_DATA_MSG_SOURCE_CAP_PPS_APDU_t *p_cap_pps;
                    p_cap_pps = (volatile UPD_DATA_MSG_SOURCE_CAP_PPS_APDU_t *)&tx_data[UPD_MSG_HEAD_LEN+obj_num*UPD_MSG_DATA_OBJ_SIZE];
                    if ((CURRENT_3000mA / CURRENT_PPS_DIV) < usbpd_cfg_port_src_pps_pwr_max_curr_get(i))
                    {
                        p_cap_pps->max_curr = usbpd_cfg_port_src_pps_pwr_max_curr_get(i);
                        dpm_tx_src_cap_gt_3a_flag_set(TRUE);
                    }
                    obj_num++;
                }
            }
        }
    }
}

void sys_pd_vdm_disc_ident_ack_received_hook(u32_t arg)
{
#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        drv_uart_puts("\nVDM DISC IDENT ACK Hook");
    }
#endif /* CLI_ENABLED */

    // Change power policy here
    if (MSG_SOP_TYPE_SOPP == dpm_msg_sop_type_get())
    {
        sys_pd_power_policy_process(TRUE);
    }
}

void sys_pd_prl_msg_request_hook(u8_t *p_msg, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_msg)
        return;

    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Request Hook:\n");
    }
#if 0
    if (dir == PRL_MSG_DIR_TX)
    {
        volatile UPD_DATA_MSG_REQUEST_FIXED_VARIABLE_t *p_req_fixed = (volatile UPD_DATA_MSG_REQUEST_FIXED_VARIABLE_t *)(p_msg+UPD_MSG_HEAD_LEN);
        if (dpm_rx_src_cap_mismatch_get())
        {
            p_req_fixed->cap_mismatch = FALSE;
            u32_t opr_curr;
            u32_t max_curr;
            if (dpm_src_obj_pos_get())
            {
                p_req_fixed->obj_pos = dpm_src_obj_pos_get();
                opr_curr = ((volatile UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(dpm_src_obj_pos_get()-1))->max_curr;
                max_curr = opr_curr * CURRENT_DIV;
                if (max_curr < CURRENT_2250mA)
                {
                    dpm_src_obj_pos_set(1);
                    p_req_fixed->obj_pos = 1; //vSafe5V
                    opr_curr = ((volatile UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(0))->max_curr;
                }
                p_req_fixed->opr_curr = opr_curr;
                p_req_fixed->max_opr_curr = opr_curr;
            }
        }
    }
#endif
}

#define VDM_DISC_IDENT_ACK_LEN  22
#if 0  /* deleted by James Gan - 2020-03-10 */
u8_t s_disc_ident_ack[VDM_DISC_IDENT_ACK_LEN] = {
    0x4F, 0x51,
    0x41, 0x80, 0x00, 0xFF, 0x85, 0x2F, 0x00, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x08, 0x11
    };
#endif /* #if 0 */


void sys_pd_prl_msg_vdm_attention_hook(UPD_DATA_MSG_VDM_ATTENTION_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("VDM Attention Hook:\n");
    }
#endif /* CLI_ENABLED */
}


void sys_pd_prl_msg_vdm_unstructured_hook(u8_t *p_msg, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_msg)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Unstructured VDM Hook:\n");
    }
#endif /* CLI_ENABLED */
    if (PRL_MSG_DIR_RX == dir)
    {
        pe_unsupported_msg_received_set(TRUE);
    }
}

void sys_pd_prl_msg_alert_hook(UPD_DATA_MSG_ALERT_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_puts("Alert Hook:");
        printf(" %-24s: %02X\n", "Type", p_info->type);
        if (p_info->type > 0)
        {
            if (p_info->type & UPD_ALERT_TYPE_RSVD1)
            {
                drv_uart_puts("  Bit0: Reserved");
            }
            if (p_info->type & UPD_ALERT_TYPE_BAT_STA_CHG)
            {
                drv_uart_puts("  Bit1: Battery Status Change");
            }
            if (p_info->type & UPD_ALERT_TYPE_OCP)
            {
                drv_uart_puts("  Bit2: Over-Current Protection");
            }
            if (p_info->type & UPD_ALERT_TYPE_OTP)
            {
                drv_uart_puts("  Bit3: Over-Temperature Protection");
            }
            if (p_info->type & UPD_ALERT_TYPE_OPR_COND_CHG)
            {
                drv_uart_puts("  Bit4: Operating Condition Change");
            }
            if (p_info->type & UPD_ALERT_TYPE_SRC_INPT_CHG)
            {
                drv_uart_puts("  Bit5: Source Input Change");
            }
            if (p_info->type & UPD_ALERT_TYPE_OVP)
            {
                drv_uart_puts("  Bit6: Over-Voltage Protection");
            }
            if (p_info->type & UPD_ALERT_TYPE_RSVD2)
            {
                drv_uart_puts("  Bit7: Reserved");
            }
        }

        printf(" %-24s: %02X\n %-24s: %02X\n",
            "Fixed Batteries", p_info->fixed_batteries,
            "Hot Swappable Batteries", p_info->hot_swappable_batteries);
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_get_country_info_hook(UPD_DATA_MSG_GET_COUNTRY_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        printf("Get Country Info Hook:\n %-24s: %c%c\n",
            "Country Code", p_info->alpha_2_code_1, p_info->alpha_2_code_2);
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_battery_status_hook(UPD_DATA_MSG_BATTERY_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        printf("Battery Status Hook:\n %-24s: %02X\n %-24s: %u\n",
            "Info", p_info->info,
            "Capacity", p_info->present_capacity);
    }
#endif /* CLI_ENABLED */
    if (dir == PRL_MSG_DIR_TX)
    {
        if (g_sys_pd_info.invalid_bat_sta_ref)
        {
            p_info->info = 1; // Invalid Battery reference
            p_info->present_capacity = 0xFFFF;
            p_info->resv = 0;
            g_sys_pd_info.invalid_bat_sta_ref = 0;
        }
    }
    else {

    }
}

void sys_pd_prl_msg_ext_src_cap_hook(UPD_EXT_MSG_SRC_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        printf("Extended Source Capability Hook:\n %-24s: %02X\n %-24s: %u\n",
            "Batteries", p_info->batteries,
            "PDP", p_info->src_pdp);
        printf("Configuration:\n %-24s: %02X\n %-24s: %u\n",
            "Batteries", usbpd_cfg_port_battery_num_get(),
            "PDP", usbpd_cfg_port_src_pdp_get());
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_ext_status_hook(UPD_EXT_MSG_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Status Hook:\n");
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_ext_get_bat_cap_hook(UPD_EXT_MSG_GET_BAT_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Get Battery Capability Hook:\n");
    }
#endif /* CLI_ENABLED */
    if (dir == PRL_MSG_DIR_TX)
    {

    }
    else {
        if (p_info->bat_cap_ref > 0)
        {
            g_sys_pd_info.invalid_bat_cap_ref = 1;
        }
    }
}

void sys_pd_prl_msg_ext_get_bat_status_hook(UPD_EXT_MSG_GET_BAT_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Get Battery Status Hook:\n");
    }
#endif /* CLI_ENABLED */
    if (dir == PRL_MSG_DIR_TX)
    {

    }
    else {
        if (p_info->bat_status_ref > 0)
        {
            g_sys_pd_info.invalid_bat_sta_ref = 1;
        }
    }
}

void sys_pd_prl_msg_ext_bat_cap_hook(UPD_EXT_MSG_BAT_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Battery Capability Hook:\n");
    }
#endif /* CLI_ENABLED */
    if (dir == PRL_MSG_DIR_TX)
    {
        if (g_sys_pd_info.invalid_bat_cap_ref)
        {
            p_info->type = 1; // Invalid Battery reference
            p_info->design_capacity = 0xFFFF;
            g_sys_pd_info.invalid_bat_cap_ref = 0;
        }
    }
    else {

    }
}


void sys_pd_prl_msg_ext_get_mfr_info_hook(UPD_EXT_MSG_GET_MFR_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Get Manufacturer Info Hook:\n");
        if (1 == p_info->mfr_info_target)
        {
            printf(" Battery Reference: %u\n", p_info->mfr_info_ref);
        }
    }
#endif /* CLI_ENABLED */

    if (dir == PRL_MSG_DIR_RX)
    {
        g_sys_pd_info.rx_get_mfr_info.mfr_info_target = p_info->mfr_info_target;
        g_sys_pd_info.rx_get_mfr_info.mfr_info_ref = p_info->mfr_info_ref;
    }
}

void sys_pd_prl_msg_ext_mfr_info_hook(UPD_EXT_MSG_MFR_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Manufacturer Info Hook:\n");
        printf(" %-24s: %u\n", "VID", p_info->vid);
        printf(" %-24s: %u\n", "PID", p_info->pid);
        printf(" %-24s: %s\n", "String", p_info->mfr_str);
    }
#endif /* CLI_ENABLED */

    if (dir == PRL_MSG_DIR_TX)
    {
        if ((g_sys_pd_info.rx_get_mfr_info.mfr_info_target != 0) ||
            (g_sys_pd_info.rx_get_mfr_info.mfr_info_ref != 0))
        {
            memset((char *)p_info->mfr_str, 0, UPD_EXT_MSG_MFR_MAX_STRING_LEN);
            strcpy((char *)p_info->mfr_str, "Not Supported");
        }
    }
}


void sys_pd_prl_msg_ext_secur_req_hook(UPD_EXT_MSG_SECURITY_REQ_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{

}

void sys_pd_prl_msg_ext_secur_resp_hook(UPD_EXT_MSG_SECURITY_RESP_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{

}


void sys_pd_prl_msg_ext_fw_up_req_hook(void *p_info, PRL_MSG_DIR_TYPE_t dir)
{

}

void sys_pd_prl_msg_ext_fw_up_resp_hook(void *p_info, PRL_MSG_DIR_TYPE_t dir)
{

}


void sys_pd_prl_msg_ext_pps_status_hook(UPD_EXT_MSG_PPS_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended PPS Status Hook:\n");
    }
#endif /* CLI_ENABLED */
}


void sys_pd_prl_msg_ext_country_info_hook(UPD_EXT_MSG_COUNTRY_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Country Info Hook:\n");
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_ext_country_codes_hook(UPD_EXT_MSG_COUNTRY_CODES_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Country Codes Hook:\n");
    }
#endif /* CLI_ENABLED */
}


void sys_pd_prl_msg_ext_snk_cap_hook(UPD_EXT_MSG_SNK_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir)
{
    if (!p_info)
        return;

#if CLI_ENABLED
    if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2)
    {
        if (dir == PRL_MSG_DIR_TX)
        {
            drv_uart_putstr("\nTX ");
        }
        else {
            drv_uart_putstr("\nRX ");
        }
        drv_uart_putstr("Extended Sink Capability Hook:\n");
    }
#endif /* CLI_ENABLED */
}


void sys_pd_hook_init()
{
    memset((void *)&g_sys_pd_info, 0, sizeof(SYS_PD_INFO_t));

    g_sys_pd_info.sys_initializing = TRUE;

    sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
   //g_sys_pd_info.usbc_power_ctrl_en = FALSE;
#if SYS_PWM_CTRL_VOLT_ENABLED
    if (usbpd_cfg_port_src_pwm_en_get())
    {
        if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
        {
            drv_pwm_en_set(SYS_PWM_INDEX_FOR_VOLT_CTRL,FALSE);
        }
        else {
            drv_pwm_init_set(SYS_PWM_INDEX_FOR_VOLT_CTRL,TRUE,usbpd_cfg_port_src_pwm_per_get());
            drv_pwm_duty_set2(SYS_PWM_INDEX_FOR_VOLT_CTRL, usbpd_cfg_port_src_fixed_pwr_pwm_duty_get(CFG_VOLTAGE_5V_IDX));
            drv_pwm_en_set(SYS_PWM_INDEX_FOR_VOLT_CTRL,usbpd_cfg_port_src_pwm_en_get());
        }
    }
#endif /* SYS_PWM_CTRL_VOLT_ENABLED */

#if SYS_QUICK_CHARGE_ENABLED
    sys_qc_init();
#else
#if SYS_UFCS_ENABLED
    sys_bc_qc_init();
#endif
#endif

    usbpd_cc_hook_set(snk,unattached, sys_pd_sink_unattached_hook);
    usbpd_cc_hook_set(snk,attachwait, sys_pd_sink_attachwait_hook);
    usbpd_cc_hook_set(snk,attached, sys_pd_sink_attached_hook);
    usbpd_cc_hook_set(src,unattached, sys_pd_source_unattached_hook);
    usbpd_cc_hook_set(src,attachwait, sys_pd_source_attachwait_hook);
    usbpd_cc_hook_set(src,attached, sys_pd_source_attached_hook);

    usbpd_snk_transit_to_new_power_hook_set(sys_pd_sink_transit_to_new_power_hook);
    usbpd_src_transit_to_new_power_hook_set(sys_pd_source_transit_to_new_power_hook);

    usbpd_hook_set(src_vbus_en, sys_pd_vbus_source_en_set);
    usbpd_hook_set(discharge_en, sys_pd_vbus_discharge_en_set);
    usbpd_hook_set(cc1_vconn_en, sys_pd_cc1_vconn_en_set);
    usbpd_hook_set(cc2_vconn_en, sys_pd_cc2_vconn_en_set);

    usbpd_hook_with_return_set(src_vbus_en, sys_pd_vbus_source_en_get);
    usbpd_hook_with_return_set(discharge_en, sys_pd_vbus_discharge_en_get);
    usbpd_hook_with_return_set(cc1_vconn_en, sys_pd_cc1_vconn_en_get);
    usbpd_hook_with_return_set(cc2_vconn_en, sys_pd_cc2_vconn_en_get);
    usbpd_hook_with_return_set(c1_vbus_volt, sys_usbc_vbus_get);

    usbpd_event_hook_set(prs_started, sys_pd_prs_started_hook);
    usbpd_event_hook_set(prs_completed, sys_pd_prs_completed_hook);
    usbpd_event_hook_set(drs_started, sys_pd_drs_started_hook);
    usbpd_event_hook_set(drs_completed, sys_pd_drs_completed_hook);
    usbpd_event_hook_set(vcs_started, sys_pd_vcs_started_hook);
    usbpd_event_hook_set(vcs_completed, sys_pd_vcs_completed_hook);
    usbpd_event_hook_set(power_change_req, sys_pd_power_change_req_hook);
    usbpd_event_hook_set(idle, sys_pd_idle_hook);
    usbpd_event_hook_set(vdm_disc_ident_ack_received, sys_pd_vdm_disc_ident_ack_received_hook);
    usbpd_event_hook_set(prl_msg_received, sys_pd_prl_msg_received_hook);
    usbpd_event_hook_set(prl_msg_sent, sys_pd_prl_msg_sent_hook);
    usbpd_event_hook_set(epr_enter_fail, sys_pd_epr_enter_fail_hook);

    usbpd_prl_msg_hook_set(source_capabilities, (v_func_args_ptr_t)sys_pd_prl_msg_src_cap_hook);
    usbpd_prl_msg_hook_set(request, (v_func_args_ptr_t)sys_pd_prl_msg_request_hook);
    usbpd_prl_msg_hook_set(vdm_attention, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_attention_hook);
    usbpd_prl_msg_hook_set(vdm_unstructured, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_unstructured_hook);


    usbpd_prl_msg_hook_set(alert, (v_func_args_ptr_t)sys_pd_prl_msg_alert_hook);
    usbpd_prl_msg_hook_set(get_country_info, (v_func_args_ptr_t)sys_pd_prl_msg_get_country_info_hook);
    usbpd_prl_msg_hook_set(battery_status, (v_func_args_ptr_t)sys_pd_prl_msg_battery_status_hook);
    usbpd_prl_msg_hook_set(ext_src_cap, (v_func_args_ptr_t)sys_pd_prl_msg_ext_src_cap_hook);
    usbpd_prl_msg_hook_set(ext_status, (v_func_args_ptr_t)sys_pd_prl_msg_ext_status_hook);
    usbpd_prl_msg_hook_set(ext_get_bat_cap, (v_func_args_ptr_t)sys_pd_prl_msg_ext_get_bat_cap_hook);
    usbpd_prl_msg_hook_set(ext_get_bat_status, (v_func_args_ptr_t)sys_pd_prl_msg_ext_get_bat_status_hook);
    usbpd_prl_msg_hook_set(ext_bat_cap, (v_func_args_ptr_t)sys_pd_prl_msg_ext_bat_cap_hook);
    usbpd_prl_msg_hook_set(ext_get_mfr_info, (v_func_args_ptr_t)sys_pd_prl_msg_ext_get_mfr_info_hook);
    usbpd_prl_msg_hook_set(ext_mfr_info, (v_func_args_ptr_t)sys_pd_prl_msg_ext_mfr_info_hook);
    usbpd_prl_msg_hook_set(ext_secur_req, (v_func_args_ptr_t)sys_pd_prl_msg_ext_secur_req_hook);
    usbpd_prl_msg_hook_set(ext_secur_resp, (v_func_args_ptr_t)sys_pd_prl_msg_ext_secur_resp_hook);
    usbpd_prl_msg_hook_set(ext_fw_up_req, (v_func_args_ptr_t)sys_pd_prl_msg_ext_fw_up_req_hook);
    usbpd_prl_msg_hook_set(ext_fw_up_resp, (v_func_args_ptr_t)sys_pd_prl_msg_ext_fw_up_resp_hook);
    usbpd_prl_msg_hook_set(ext_pps_status, (v_func_args_ptr_t)sys_pd_prl_msg_ext_pps_status_hook);
    usbpd_prl_msg_hook_set(ext_country_info, (v_func_args_ptr_t)sys_pd_prl_msg_ext_country_info_hook);
    usbpd_prl_msg_hook_set(ext_country_codes, (v_func_args_ptr_t)sys_pd_prl_msg_ext_country_codes_hook);
    usbpd_prl_msg_hook_set(ext_snk_cap, (v_func_args_ptr_t)sys_pd_prl_msg_ext_snk_cap_hook);
}


