/**
 * \file    sys_pd_hook.c
 * \brief   
 * 
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-08-31
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-08-31  Original Creation
 * 
 */

#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"
#include "sys_bat_intf.h"
#include "sys_pd_config.h"
#include "sys_qc_hook.h"
#if SYS_SMG_DISPLAY_ENABLED
#include "sys_smg_display.h"
#endif /* SYS_SMG_DISPLAY_ENABLED */


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 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 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          (6505)

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

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

/** Temperature greater than 40C, restore charge 
 *  Temperature lower than 40C, disable charge
 */
#define DPM_TEMP_P40C_VOLT          (11443)

/** Temperature greater than 0C, restore charge 
 *  Temperature lower than 0C, disable charge
 */

#define DPM_TEMP_0C_VOLT            (25264)

/** Temperature greater than -10C, restore discharge, but still disable charge
 *  Temperature lower than -10C, disable charge and discharge
 */
#define DPM_TEMP_M10C_VOLT          (27931)
/** Temperature greater than -20C, restore discharge, but still disable charge
 *  Temperature lower than -20C, disable charge and discharge
 */
#define DPM_TEMP_M20C_VOLT          (29731)


#define DPM_TEMP_INVALID_VOLT       (32600)

#endif /* SYS_OVERTEMP_DECTION_ENABLED */
/*uint ma 8812 max set*/
#define SC881X_IBAT_SET_LIMIT       (12000)
#define SC881X_IBUS_SET_LIMIT_MIN   (320)

void sys_pd_hpd_start_time_set(sys_tick_t time)
{
    //sync_enter_critical();
    g_sys_pd_info.hpd_detect_start_time = time;
    //sync_exit_critical();
}
void sys_gpio_hpd_isr(u32_t arg)
{
    g_sys_pd_info.hpd_last_state = g_sys_pd_info.hpd_state;
    // 读当前值，0有效
    g_sys_pd_info.hpd_state = sys_gpio_hpd_out_detect();

    if (!g_sys_pd_info.hpd_state) // 如果是low
    {
        // 设置上升沿，触发下一次中断
        drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, 1);
        sys_pd_hpd_start_time_set(now());
    }
    else
    {
        // 设置下降沿，触发下一次中断
        sys_tick_t hpd_current_time = now();
        drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, 0);
        if ((g_sys_pd_info.hpd_detect_start_time) && 
            (hpd_current_time > g_sys_pd_info.hpd_detect_start_time) && 
            ((hpd_current_time - g_sys_pd_info.hpd_detect_start_time) >= (SYS_HPD_IRQ_DETECT_DURATION_MIN)) &&
            ((hpd_current_time - g_sys_pd_info.hpd_detect_start_time) <= (SYS_HPD_IRQ_DETECT_DURATION_MAX)))
        {
            // hpd irq
            g_sys_pd_info.ufp_d_sta.hpd_sta = 1;
            g_sys_pd_info.ufp_d_sta.irq_hpd = 1;
            g_sys_pd_info.attention_req_flg = 1;
        }
        else if ((g_sys_pd_info.hpd_detect_start_time) && 
            (hpd_current_time > g_sys_pd_info.hpd_detect_start_time) && 
            ((hpd_current_time - g_sys_pd_info.hpd_detect_start_time) > (SYS_HPD_HOT_INSERT_DETECT_DURATION_MAX)))
        {
            // hpd low to high
            g_sys_pd_info.ufp_d_sta.hpd_sta = 1;
            g_sys_pd_info.ufp_d_sta.irq_hpd = 0;
            g_sys_pd_info.attention_req_flg = 1;
            g_sys_pd_info.hpd_irq_cnt = 0;
        }
        sys_pd_hpd_start_time_set(0);
    }
}
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);
        sys_gpio_uart0_enable_set(TRUE);
    }
    else {
        if (DRV_UART_ID_0 == drv_uart_default_get())
        {
            if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(TRUE);
        }
        else {
            sys_gpio_uart0_enable_set(TRUE);
        }
    }
#else
    if (DRV_UART_ID_0 == drv_uart_default_get())
    {
        if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(TRUE);
    }
    else {
        sys_gpio_uart0_enable_set(TRUE);
    }
#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 */

#if 0 //SYS_POWER_BANK_ENABLED
    sys_bat_charge_enable(FALSE);
#endif /* SYS_POWER_BANK_ENABLED */
    sys_gpio_vbus_en_set(FALSE);
    sys_gpio_pd_qc_led_off();
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
#if 0
    //sys_pd_power_policy_process(TRUE);
    //g_sys_pd_info.c1_ctrl.idle = TRUE;
    //g_sys_pd_info.c1_ctrl.charge = FALSE;
    //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
#endif
   
#if (!UARt1_disable_set)   
    sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
    //g_sys_pd_info.upd1_rate_pwr = 0;
  
    //sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);    
#endif
    g_sys_pd_info.pd_power_nego_completed = FALSE;
    sys_gpio_xsd1_set(FALSE);
    sys_gpio_xsd2_set(FALSE);
}

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 SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        sys_gpio_uart0_enable_set(FALSE);
        if (!dpm_port_dead_battery_get())
        {
            // No need to enable QC sink
            dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
        }
    }
    else {
        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);
        }
    }
#else
    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) 
    {
        drv_uart_puts("\nSink Attached Hook");
    }
#endif /* CLI_ENABLED */
    sys_gpio_vbus_en_set(FALSE);
    sys_gpio_pstop_set(TRUE);
#if 0 //SYS_POWER_BANK_ENABLED
    sys_bat_charge_enable(TRUE);
#endif /* SYS_POWER_BANK_ENABLED */

    g_sys_pd_info.c1_ctrl.idle = FALSE;
    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);

#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    //sys_pd_power_policy_process(TRUE);
    //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
#if (!UARt1_disable_set)
    g_sys_pd_info.upd1_sta.connect = TRUE;
    g_sys_pd_info.upd1_sta.charge = TRUE;
    sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
    //sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);
#endif
}

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 (!g_sys_pd_info.c2_sta.charging)
    {
        if (FALSE == sys_gpio_chip_en_get())
        {
            sys_gpio_chip_en_set(TRUE);
        }
        sys_gpio_pstop_set(TRUE);
#if 0 /*SYS_POWER_BANK_ENABLED*/
        sys_bat_charge_enable(TRUE);
#endif /* SYS_POWER_BANK_ENABLED */
        g_sys_pd_info.c1_ctrl.charge = TRUE;
    }
    else 
    {
        sys_gpio_pstop_set(FALSE);
        g_sys_pd_info.c1_ctrl.charge = FALSE;
    }
    sys_gpio_pd_qc_led_on();
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

    if ((!pe_hard_reset_in_prog()) && (!pe_prs_in_prog_get()))
    {
        g_sys_pd_info.pd_power_nego_completed = TRUE;
    }

    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);
        sys_gpio_uart0_enable_set(TRUE);
    }
    else {
        if (DRV_UART_ID_0 == drv_uart_default_get())
        {
            if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(TRUE);
        }
        else {
            sys_gpio_uart0_enable_set(TRUE);
        }
    }
#else
    if (DRV_UART_ID_0 == drv_uart_default_get())
    {
        if (SYS_DEBUG_LEVEL_OFF == sys_cfg_dbg_get()) sys_gpio_uart0_enable_set(TRUE);
    }
    else {
        sys_gpio_uart0_enable_set(TRUE);
    }
#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 */
#if 0
    sys_bat_charge_enable(FALSE);
#endif /* SYS_POWER_BANK_ENABLED */
    sys_gpio_vbus_en_set(FALSE);
    g_sys_pd_info.c1_current_pwr = 0;
    sys_gpio_pd_qc_led_off();
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    sys_gpio_chip_en_set(FALSE);
    g_sys_pd_info.pd_power_nego_completed = FALSE;
    g_sys_pd_info.pd_disc_ident_req = 0;
    g_sys_pd_info.pd_partner_soft_reset_req = 0;
    //sys_pd_power_policy_process(TRUE);
    g_sys_pd_info.c1_disconnet_tick = g_sys_pd_info.continuous_timer_tick;

#if (!UARt1_disable_set)
    sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
    //g_sys_pd_info.upd1_rate_pwr = 0;
    //sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);
#endif
    sys_gpio_sbuon_set(FALSE);
    g_sys_pd_info.dp_mode_flg = FALSE;
    g_sys_pd_info.attention_req_flg = FALSE;
    drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, FALSE);
    drv_gpio_intr_en_set(SYS_IO_HPD_OUT, FALSE);
    g_sys_pd_info.dr_swap_cnt = 0;
    sys_gpio_xsd1_set(FALSE);
    sys_gpio_xsd2_set(FALSE);
    sys_gpio_dps2_set(FALSE);
    sys_gpio_dps1_set(FALSE);
}

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_gpio_chip_en_get())
    {
        sys_gpio_chip_en_set(TRUE);
    }
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        sys_gpio_uart0_enable_set(FALSE);
        drv_chip_dp0_dm0_short_set(TRUE);
        if (!dpm_port_dead_battery_get())
        {
            dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
        }
    }
    else {
        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);
        }
    }
#else
    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 */

    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 (!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);
    }

    g_sys_pd_info.rated_vbus = VSAFE_5V,
    g_sys_pd_info.rated_ibus = 3000;
    //g_sys_pd_info.upd1_rate_pwr = 15;
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    if ((g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.c1_disconnet_tick) &&
        ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.c1_disconnet_tick) >= 6))
    {
        sys_pd_power_policy_process(TRUE);
    }
    if(!g_sys_pd_info.c2_sta.conn)
    {
        g_sys_pd_info.c1_c2_insert_state = SYS_C1_FST_INSERT;

    }
#if (!UARt1_disable_set)
    sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
    //sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);
#endif
    ///sys_gpio_sbuon_set(true);
    if (!dpm_orient_select_get())
    {
        //sys_gpio_sbusw_set(TRUE);
        sys_gpio_sbusw_set(FALSE);
    }
    else
    {
        //sys_gpio_sbusw_set(FALSE);
        sys_gpio_sbusw_set(TRUE);
    } 
    g_sys_pd_info.hpd_irq_cnt = 0;
}

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))
    {
        //current = REQ_PPS_OPR_CURR_GET(dpm_current_rdo_get())*CURRENT_PPS_DIV;
        current = usbpd_cfg_port_src_pps_pwr_max_curr_get(pos)*CURRENT_PPS_DIV;
        if(dpm_rx_vdm_ack_cable_vbus_curr_cap_get()==VBUS_CURR_HANDLING_CAP_5A)
        {
            
        }
        else
        {
            if(current>3000)
            {
                current = 3000;
            }
        }
        voltage = REQ_PPS_OUTPUT_VOLT_GET(dpm_current_rdo_get())*VOLTAGE_PPS_REQ_DIV;
    }
    else 
    {
        //current = usbpd_cfg_port_src_fixed_pwr_curr_cap_get(pos)*CURRENT_DIV;
        current = (MAX_OPR_CURR_GET((UPD_DATA_MSG_REQUEST_FIXED_VARIABLE_t *)dpm_current_rdo_get())*CURRENT_DIV);
        voltage = usbpd_cfg_port_src_fixed_pwr_volt_cap_get(pos)*VOLTAGE_DIV;
    }

    if ((!pe_hard_reset_in_prog()) && (!pe_prs_in_prog_get()))
    {
        g_sys_pd_info.c1_ctrl.charge = FALSE;
        g_sys_pd_info.rated_vbus = voltage,
        g_sys_pd_info.rated_ibus = current;
        //g_sys_pd_info.upd1_rate_pwr = voltage * current / 1000000;
        g_sys_pd_info.pd_power_nego_completed = TRUE;
        //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
#if 0//(!UARt1_disable_set)
        sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);
#endif
    }

    voltage += SYS_POWER_BANK_VOLTAGE_COMPENSATION;

    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_gpio_vbus_en_set(TRUE);
    if(current> 5400)
    {
        current = 5400;
    }
    sys_bat_discharge_vbus_ibus_set(voltage, current+500);

    if (CFG_VOLTAGE_5V_IDX != pos)
        sys_gpio_pd_qc_led_on();

    return S_OK;
}

bool_t sys_pd_vbus_source_en_get(void)
{
    return g_sys_pd_info.vbus_source_en;
}

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 (old_flg != flg)
	{
#if CLI_ENABLED
        if (usbpd_cfg_dbg_get() >= USBPD_DEBUG_LEVEL_2) 
        {
            printf("\nVBUS_SRC_ON(%u)\n",flg);
        }
#endif /* CLI_ENABLED */
        if ((flg) && (FALSE == sys_gpio_chip_en_get()))
        {
            sys_gpio_chip_en_set(flg);
        }
    }

    if (flg)
    {
        sys_bat_discharge_vbus_ibus_set(VSAFE_5V+SYS_POWER_BANK_VOLTAGE_COMPENSATION, CURRENT_3000mA);
        sys_gpio_pstop_set(TRUE);
        sys_gpio_vbus_en_set(TRUE);
    }
    else {
        sys_bat_discharge_vbus_ibus_set(0, 0);
        sys_gpio_vbus_en_set(FALSE);
        sys_gpio_pstop_set(FALSE);
    }
}

bool_t sys_pd_vbus_discharge_en_get(void)
{
    return dpm_vbus_discharge_get();
}

void sys_pd_vbus_discharge_en_set(bool_t flg)
{
    dpm_vbus_discharge_set(flg);
}

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 */
    dpm_req_spec_rev_set(0);
}

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())
    {
        //g_sys_pd_info.c1_ctrl.charge = FALSE;
        //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
    }
}

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++;
}

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)
{
    //u32_t total_pwr = g_sys_pd_info.c1_current_pwr + g_sys_pd_info.c2_current_pwr;
    //u32_t C1_power_idx = usbpd_cfg_port_src_fixed_pwr_prof_get();
    u32_t C2_power_idx = g_sys_pd_info.c2_power_profile;
    
    if (sys_bat_capacity_get() >= 50)
    {
        
        if (((dpm_cable_detect_done_get()) && ((u32_t)(now() - dpm_cc_connection_changed_time_get()) > 1500000UL)) || 
            (change_asap))
        {
            if ((!g_sys_pd_info.c2_sta.conn) && 
                ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.c2_conn_changed_tick) >= 20))
            {
                
                if(g_sys_pd_info.usba_no_current_flow_flag)
                {
                    C2_power_idx = POWER_PROFILE_65W_PPS;
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                }
                else
                {
                    if(sys_gpio_usba1_power_on_get()&&(g_sys_pd_info.usba1_indet_flag))
                    {
                        C2_power_idx = POWER_PROFILE_65W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        //sys_gpio_usba_qc_on_set(FALSE);
                        if(!sys_gpio_usba_qc_on_get())
                        {
                            sys_gpio_usba_qc_on_set(TRUE);
                        }
                    }
                }
                if(g_sys_pd_info.c1_ctrl1.discharge_off)
                {

                    g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                    
                    //sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                }
                if( g_sys_pd_info.c1_attached_discharge_off_flag )
                {
                    g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                    //sys_gpio_vbus_en_set(FALSE);
                    if ((dpm_cable_detect_done_get()) && 
                        (dpm_current_pwr_mode_get()))
                    {
                        if (pe_pd_connected_get())
                        {
                            dpm_hard_reset_req_set(TRUE);
                            pe_state_machine();
                        }
                        else {
                            dpm_vbus_source_en_set(TRUE);
                        }
                    }

               }
            }
            else {
                if ((g_sys_pd_info.pd_power_nego_completed) && 
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed) &&
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    (g_sys_pd_info.c2_sta.pr_mode))
                {
                   
                    if (g_sys_pd_info.usba_no_current_flow_flag)
                    {

                        if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_18W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_45W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                            }
                        }
                        else if(g_sys_pd_info.c1_current_pwr >= g_sys_pd_info.c2_current_pwr)
                        {
                            C2_power_idx = POWER_PROFILE_18W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                        }
                        else
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                        }
                    }
                    else 
                    {
                        if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                            
                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_7P5W_FIXED;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_45W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_7P5W_FIXED);
                            }

                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr < 45))
                        {
                            C2_power_idx = POWER_PROFILE_7P5W_FIXED;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                            
                        }
                        else if((g_sys_pd_info.c1_current_pwr < 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_7P5W_FIXED);

                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 30) && (g_sys_pd_info.c2_current_pwr >= 30))
                        {

                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_18W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_30W_PPS_20V);
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                            }
                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 30) && (g_sys_pd_info.c2_current_pwr < 30))
                        {
                                C2_power_idx = POWER_PROFILE_18W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_30W_PPS_20V);
                        }
                        else if((g_sys_pd_info.c1_current_pwr < 30) && (g_sys_pd_info.c2_current_pwr >= 30))
                        {
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);

                        }
                        else{
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                        }

                        sys_gpio_usba_qc_on_set(FALSE);
                    }
                }
                else if(/*(g_sys_pd_info.pd_power_nego_completed)&&*/
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed)&&
                    (dpm_port_state_get()==DPM_PORT_STATE_CHARGE)&&
                    (g_sys_pd_info.c1_ctrl.charge)&&
                    (g_sys_pd_info.c2_sta.pr_mode))
                {
#if 0
                    if((!dpm_port_dead_battery_get())&&((!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag))&&
                        (!dpm_source_ocp_flag_get()))
                    {
                        if(g_sys_pd_info.c1_ctrl1.discharge_off)
                        {
                            g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));
                           
                        }

                    }
                    
                    if((!dpm_port_dead_battery_get())&&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag)&&
                    (!g_sys_pd_info.usba_ocp_flag))
                    {
                        if(g_sys_pd_info.usba1_indet_flag&&(!sys_gpio_usba1_power_on_get()))
                        {
                             sys_usba_restore();
                            
                        }

                    }
#endif                    
                    if(g_sys_pd_info.c1_current_pwr > 65)
                    {

                        C2_power_idx = POWER_PROFILE_65W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);

                    }
                    else if(g_sys_pd_info.c1_current_pwr == 65)
                    {
                        if(g_sys_pd_info.usba_no_current_flow_flag)
                        {
                            C2_power_idx = POWER_PROFILE_65W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
            
                        }
                        else
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                        }
                    }
                    else if(g_sys_pd_info.c1_current_pwr >=45)
                    {  
#if 0
                        C2_power_idx = POWER_PROFILE_CUSTOMIZE_FIXED;
                        g_sys_pd_info.c2_power_profile = POWER_PROFILE_CUSTOMIZE_FIXED;
                        
                        u8_t temp = g_sys_pd_info.c1_current_pwr&0x00ff;
                        sys_master_charge_pwr_reg_set(temp); 
#endif                  
                         C2_power_idx = POWER_PROFILE_45W_PPS;
                         sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);                  
                    }
                    else
                    {
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                    }
                }
                else if(g_sys_pd_info.pd_power_nego_completed&&
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    (!g_sys_pd_info.c2_sta.pr_mode)&&
                    (g_sys_pd_info.c2_sta.charging))
                {
#if 0
                    if((!dpm_port_dead_battery_get())&&((!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag))&&
                        (!dpm_source_ocp_flag_get()))
                    {
                        if(g_sys_pd_info.c1_attached_discharge_off_flag)
                        {
                            g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                            if ((dpm_cable_detect_done_get()) && 
                            (dpm_current_pwr_mode_get()))
                            {
                                if (pe_pd_connected_get())
                                {
                                    dpm_hard_reset_req_set(TRUE);
                                    pe_state_machine();
                                }
                                else {
                                        dpm_vbus_source_en_set(TRUE);
                                }
                            }
                        }
                    }
                    if((!dpm_port_dead_battery_get())&&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag)&&
                    (!g_sys_pd_info.usba_ocp_flag))
                    {

                        if(g_sys_pd_info.usba1_indet_flag&&(!sys_gpio_usba1_power_on_get()))
                        {
                            sys_usba_restore();

                        }
                    }
#endif                    
                    if(g_sys_pd_info.c2_current_pwr > 65)
                    {
                        C2_power_idx = POWER_PROFILE_65W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                    }
                    else if(g_sys_pd_info.c2_current_pwr == 65)
                    {
                        if(g_sys_pd_info.usba_no_current_flow_flag)
                        {
                            C2_power_idx = POWER_PROFILE_65W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);

                        }
                        else
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                        }

                    }
                    else if(g_sys_pd_info.c2_current_pwr >=45)
                    {  
#if 0                       
                        sys_pd_src_profile_set_by_pdp((u32_t)g_sys_pd_info.c2_current_pwr);
#endif
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);                              
                    }
                    else
                    {
                     
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                    }

                }            
                else if ((g_sys_pd_info.pd_power_nego_completed) && 
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    ((FALSE == g_sys_pd_info.c2_pd_sta.power_nego_completed) && 
                     (TRUE == g_sys_pd_info.c2_sta.pr_mode)))
                {
                    if (g_sys_pd_info.usba_no_current_flow_flag)
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        C2_power_idx = POWER_PROFILE_18W_PPS;
                    }
                    else
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        C2_power_idx = POWER_PROFILE_18W_PPS;
                        sys_gpio_usba_qc_on_set(FALSE);
                        
                    }
                }
                else if ((((FALSE == g_sys_pd_info.pd_power_nego_completed) &&
                     (dpm_current_pwr_mode_get())) && 
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed)
                    &&(TRUE == g_sys_pd_info.c2_sta.pr_mode)))
                {
                    if (g_sys_pd_info.usba_no_current_flow_flag)
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                    }
                    else
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_18W_PPS);
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_gpio_usba_qc_on_set(FALSE);
                    }
                }
                // restore
                if((g_sys_pd_info.c2_sta.conn)&&
                    (dpm_port_state_get()==DPM_PORT_STATE_CHARGE)&&
                    (g_sys_pd_info.c1_ctrl.charge)&&
                    (g_sys_pd_info.c2_sta.pr_mode))
                {
                    if((!dpm_port_dead_battery_get())&&((!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag))&&
                        (!dpm_source_ocp_flag_get()))
                    {
                        if(g_sys_pd_info.c1_ctrl1.discharge_off)
                        {
                            g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));
                           
                        }

                    }
                    
                    if((!dpm_port_dead_battery_get())&&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag)&&
                    (!g_sys_pd_info.usba_ocp_flag))
                    {
                        if(g_sys_pd_info.usba1_indet_flag&&(!sys_gpio_usba1_power_on_get()))
                        {
                             sys_usba_restore();
                            
                        }

                    }

                }
                else if(dpm_cable_detect_done_get()&&
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    (!g_sys_pd_info.c2_sta.pr_mode)&&
                    (g_sys_pd_info.c2_sta.charging))
                {

                    if((!dpm_port_dead_battery_get())&&((!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag))&&
                        (!dpm_source_ocp_flag_get()))
                    {
                        if(g_sys_pd_info.c1_attached_discharge_off_flag)
                        {
                            g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                            if ((dpm_cable_detect_done_get()) && 
                            (dpm_current_pwr_mode_get()))
                            {
                                if (pe_pd_connected_get())
                                {
                                    dpm_hard_reset_req_set(TRUE);
                                    pe_state_machine();
                                }
                                else {
                                        dpm_vbus_source_en_set(TRUE);
                                }
                            }
                        }
                    }
                    if((!dpm_port_dead_battery_get())&&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag)&&
                    (!g_sys_pd_info.usba_ocp_flag))
                    {

                        if(g_sys_pd_info.usba1_indet_flag&&(!sys_gpio_usba1_power_on_get()))
                        {
                            sys_usba_restore();

                        }
                    }

                }
            }
        }
        else if ((!dpm_cable_detect_done_get())&&((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.c1_conn_changed_tick) >= 20))
        {
            if(g_sys_pd_info.usba_no_current_flow_flag)
            {
                C2_power_idx = POWER_PROFILE_65W_PPS;
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);

            }
            else
            {
                if(sys_gpio_usba1_power_on_get() && (g_sys_pd_info.usba1_indet_flag))
                {
                    C2_power_idx = POWER_PROFILE_45W_PPS;
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                    //sys_gpio_usba_qc_on_set(FALSE);
                    if(!sys_gpio_usba_qc_on_get())
                    {
                        sys_gpio_usba_qc_on_set(TRUE);
                    }
                }
                
            }
            if(g_sys_pd_info.c1_ctrl1.discharge_off)
            {

                g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                
                sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

            }
            if( g_sys_pd_info.c1_attached_discharge_off_flag )
            {
                g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                //sys_gpio_vbus_en_set(FALSE);
            }
        }
    }
    else
    {
        if (((dpm_cable_detect_done_get()) && ((u32_t)(now() - dpm_cc_connection_changed_time_get()) > 1500000UL)) || 
            (change_asap))
        {
            
            if ((!g_sys_pd_info.c2_sta.conn) && 
                ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.c2_conn_changed_tick) >= 20))
            {
                if(g_sys_pd_info.usba_no_current_flow_flag)
                {
                    C2_power_idx = POWER_PROFILE_45W_PPS;
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                }
                else
                {
                    if(sys_gpio_usba1_power_on_get())
                    {

                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        sys_gpio_usba_qc_on_set(FALSE);

                    }
                    
                }
                if(g_sys_pd_info.c1_ctrl1.discharge_off)
                {

                    g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                    
                    //sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                }
                if( g_sys_pd_info.c1_attached_discharge_off_flag )
                {
                    g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                    //sys_gpio_vbus_en_set(FALSE);
                    dpm_vbus_source_en_set(TRUE);
                    if ((dpm_cable_detect_done_get()) && 
                        (dpm_current_pwr_mode_get()))
                    {
                        if (pe_pd_connected_get())
                        {
                            dpm_hard_reset_req_set(TRUE);
                            pe_state_machine();
                        }
                        else {
                            dpm_vbus_source_en_set(TRUE);
                        }
                    }

               }
                
            }
            else {
                if ((g_sys_pd_info.pd_power_nego_completed) && 
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed) &&
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    (g_sys_pd_info.c2_sta.pr_mode))/*c1 c2 discharge police*/
                {
                    if(g_sys_pd_info.usba_no_current_flow_flag)//no usba dischage
                    {
                        if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_10W_FIXED;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_45W_PPS;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);
                            }
                        }
                        else if(g_sys_pd_info.c1_current_pwr >= g_sys_pd_info.c2_current_pwr)
                        {
                            C2_power_idx = POWER_PROFILE_10W_FIXED;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                        }
                        else
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);
                        }

                        if(g_sys_pd_info.c1_ctrl1.discharge_off)
                        {
                            
                            g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                            
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                        }
                        else if( g_sys_pd_info.c1_attached_discharge_off_flag )
                        {
                            g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                            //sys_gpio_vbus_en_set(FALSE);
                            dpm_vbus_source_en_set(TRUE);
                            if ((dpm_cable_detect_done_get()) && 
                                (dpm_current_pwr_mode_get()))
                            {
                                if (pe_pd_connected_get())
                                {
                                    dpm_hard_reset_req_set(TRUE);
                                    pe_state_machine();
                                }
                                else {
                                    dpm_vbus_source_en_set(TRUE);
                                }
                            }
                            
                        }
                        
                    }
                    else
                    {
                        if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                //C2_power_idx = POWER_PROFILE_10W_FIXED;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                                if(!g_sys_pd_info.c1_ctrl1.discharge_off)
                                {
                                    g_sys_pd_info.c1_ctrl1.discharge_off = TRUE;
                                    sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                                }
                                
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_45W_PPS;
                                //sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);
                               // sys_gpio_vbus_en_set(FALSE);
                               if(!g_sys_pd_info.c1_attached_discharge_off_flag)
                               {
                                    g_sys_pd_info.c1_attached_discharge_off_flag = TRUE;
                                
                                    dpm_vbus_source_en_set(FALSE);

                               }
                                
                            }

                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 45) && (g_sys_pd_info.c2_current_pwr < 45))
                        {
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                                
                                if(!g_sys_pd_info.c1_ctrl1.discharge_off)
                                {
                                    g_sys_pd_info.c1_ctrl1.discharge_off = TRUE;
                                    sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                                }
                                
                        }
                        else if((g_sys_pd_info.c1_current_pwr < 45) && (g_sys_pd_info.c2_current_pwr >= 45))
                        {
                                C2_power_idx = POWER_PROFILE_45W_PPS;
                                //sys_gpio_vbus_en_set(FALSE);
                                if(!g_sys_pd_info.c1_attached_discharge_off_flag)
                                {
                                    dpm_vbus_source_en_set(FALSE);
                                    g_sys_pd_info.c1_attached_discharge_off_flag = TRUE;   

                                }
                                    
                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 30) && (g_sys_pd_info.c2_current_pwr >= 30))
                        {

                            if(g_sys_pd_info.c1_c2_insert_state == SYS_C1_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_10W_FIXED;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_30W_PPS_20V);
                            }
                            else if(g_sys_pd_info.c1_c2_insert_state == SYS_C2_FST_INSERT)
                            {
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);
                            }
                        }
                        else if((g_sys_pd_info.c1_current_pwr >= 30) && (g_sys_pd_info.c2_current_pwr < 30))
                        {
                                C2_power_idx = POWER_PROFILE_10W_FIXED;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_30W_PPS_20V);
                        }
                        else if((g_sys_pd_info.c1_current_pwr < 30) && (g_sys_pd_info.c2_current_pwr >= 30))
                        {
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);

                        }
                        else{
                                C2_power_idx = POWER_PROFILE_30W_PPS_20V;
                                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_10W_FIXED);
                        }
                        sys_gpio_usba_qc_on_set(FALSE);
                    }
                    
                }
                else if((dpm_port_state_get()==DPM_PORT_STATE_CHARGE)&&
                    (g_sys_pd_info.c1_ctrl.charge)&&
                    (g_sys_pd_info.c2_sta.pr_mode)&&
                    (!g_sys_pd_info.c2_sta.charging)&&
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed))
                {
                     //c1 charge,c2 discharge,battery under 13300mv ,off discharge 
                     
                     if((!g_sys_pd_info.c1_ctrl1.discharge_off)&& 
                    (!pe_prs_in_prog_get()) && 
                    (!dpm_port_dead_battery_get()) && 
                    (((sys_bat_current_vbat_val_get() > SYS_BAT_INVALID_VOLT)&&(sys_bat_current_vbat_val_get() <= 13300))||
                    ((sys_bat_capacity_get()< 3)&&(sys_bat_capacity_get()>= 0))))
                    {
                        if(g_sys_pd_info.c1_current_pwr >= 65)
                        {
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }

                        }
                        else if(g_sys_pd_info.c1_current_pwr >= 45)
                        {
                            if(!g_sys_pd_info.c1_ctrl1.discharge_off)
                            {
                                g_sys_pd_info.c1_ctrl1.discharge_off = TRUE;
                                sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));
                            }
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }

                        }
                        else
                        {
                            
                            if(!g_sys_pd_info.c1_ctrl1.discharge_off)
                            {
                                g_sys_pd_info.c1_ctrl1.discharge_off = TRUE;
                                sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));
                            }
                            
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }


                        }
                        
                    }
                    else if(g_sys_pd_info.c1_ctrl1.discharge_off)
                    {
                        if(sys_gpio_usba1_power_on_get())
                        {
                            sys_gpio_usba_qc_on_set(FALSE);
                            sys_gpio_usba1_power_on_set(FALSE); 
                        }
                    }
                    // c1 charge c2 discharge pwm police
                    if(g_sys_pd_info.c1_current_pwr > 65)
                    {
                       
                        C2_power_idx = POWER_PROFILE_65W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);  
                    }
                    else if(g_sys_pd_info.c1_current_pwr == 65)
                    {
                        if(g_sys_pd_info.usba_no_current_flow_flag)
                        {
    
                            C2_power_idx = POWER_PROFILE_65W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                        }
                        else
                        {
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);

                        }
                    }
                    else if (g_sys_pd_info.c1_current_pwr >=45)
                    {
#if 0                       
                        C2_power_idx = POWER_PROFILE_CUSTOMIZE_FIXED;
                        g_sys_pd_info.c2_power_profile = POWER_PROFILE_CUSTOMIZE_FIXED;
                        u8_t temp2 = g_sys_pd_info.c1_current_pwr&0x00ff;
                        sys_master_charge_pwr_reg_set(temp2);  
#endif   
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                    }
                    else{
                        
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                    } 
                }
                 else if((!g_sys_pd_info.c1_ctrl.charge)&&
                    (g_sys_pd_info.pd_power_nego_completed)&&
                    (dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
                    (!g_sys_pd_info.c2_sta.pr_mode)&&
                    (g_sys_pd_info.c2_sta.charging))
                {         
                    //c2 charge,c1 discharge,battery under 13300mv ,off discharge 
                    if((!g_sys_pd_info.c1_attached_discharge_off_flag)&& 
                    (!pe_prs_in_prog_get()) && 
                    (!dpm_port_dead_battery_get()) && 
                    (((sys_bat_current_vbat_val_get() > SYS_BAT_INVALID_VOLT)&&(sys_bat_current_vbat_val_get() <= 13300))||
                    ((sys_bat_capacity_get()< 3)&&(sys_bat_capacity_get()>= 0))))
                    {
                        if(g_sys_pd_info.c2_current_pwr >=65)
                        {
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }
                            
                        }
                        else if(g_sys_pd_info.c2_current_pwr >=45)
                        {
                            if(!g_sys_pd_info.c1_attached_discharge_off_flag)
                            {
                                g_sys_pd_info.c1_attached_discharge_off_flag = TRUE;
                               
                                dpm_vbus_source_en_set(FALSE);

                            }
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }

                        }
                        else 
                        {
                            if(!g_sys_pd_info.c1_attached_discharge_off_flag)
                            {
                                g_sys_pd_info.c1_attached_discharge_off_flag = TRUE;
                               
                                dpm_vbus_source_en_set(FALSE);

                            }
                            if(sys_gpio_usba1_power_on_get())
                            {
                                sys_gpio_usba_qc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                
                            }

                        }                   
                        
                        
                
                    }
                    else if(g_sys_pd_info.c1_attached_discharge_off_flag)
                    {

                        if(sys_gpio_usba1_power_on_get())
                        {
                            sys_gpio_usba_qc_on_set(FALSE);
                            sys_gpio_usba1_power_on_set(FALSE);
                            
                        }
                    }
                    // c2 charge c1 discharge ,pwr police
                    if(g_sys_pd_info.c2_current_pwr > 65)
                    {  
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                        C2_power_idx = POWER_PROFILE_65W_PPS;
                       
                    }
                    else if(g_sys_pd_info.c2_current_pwr == 65)
                    {
                        if(g_sys_pd_info.usba_no_current_flow_flag)
                        {
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_65W_PPS);
                            C2_power_idx = POWER_PROFILE_65W_PPS;
                        }
                        else
                        {
                            sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                            C2_power_idx = POWER_PROFILE_45W_PPS;
                        }

                    }
                    else if(g_sys_pd_info.c2_current_pwr >=45)
                    {
#if  0                      
                        sys_pd_src_profile_set_by_pdp((u32_t)g_sys_pd_info.c2_current_pwr);
#endif
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        
                    }
                    else{ 
                        
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        
                    }
                }
                else if ((g_sys_pd_info.pd_power_nego_completed) && 
                    (dpm_current_pwr_mode_get())&&
                    ((FALSE == g_sys_pd_info.c2_pd_sta.power_nego_completed) && 
                     (TRUE == g_sys_pd_info.c2_sta.pr_mode)))
                {
                    if(g_sys_pd_info.usba_no_current_flow_flag)
                    {
                         sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                         C2_power_idx = POWER_PROFILE_7P5W_FIXED;
                         
                        if(g_sys_pd_info.c1_ctrl1.discharge_off)
                        {

                            g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                            
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                        }
                        else if( g_sys_pd_info.c1_attached_discharge_off_flag )
                        {
                            g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                            //sys_gpio_vbus_en_set(FALSE);
                            //dpm_vbus_source_en_set(TRUE);
                            if ((dpm_cable_detect_done_get()) && 
                                (dpm_current_pwr_mode_get()))
                            {
                                if (pe_pd_connected_get())
                                {
                                    dpm_hard_reset_req_set(TRUE);
                                    pe_state_machine();
                                }
                                else {
                                    dpm_vbus_source_en_set(TRUE);
                                }
                            }
                            
                        }   
                    
                    }
                    else
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        if(!g_sys_pd_info.c1_ctrl1.discharge_off)
                        {
                            g_sys_pd_info.c1_ctrl1.discharge_off = TRUE;
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                        }
                        
                        //C2_power_idx = POWER_PROFILE_7P5W_FIXED;
                        sys_gpio_usba_qc_on_set(FALSE); 

                    } 
                }
                else if ((((FALSE == g_sys_pd_info.pd_power_nego_completed) &&
                     (dpm_current_pwr_mode_get())) && 
                    (g_sys_pd_info.c2_pd_sta.power_nego_completed)&&
                    ((TRUE == g_sys_pd_info.c2_sta.pr_mode))))
                {
                    if(g_sys_pd_info.usba_no_current_flow_flag)
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_7P5W_FIXED);
                        C2_power_idx = POWER_PROFILE_45W_PPS;

                        if(g_sys_pd_info.c1_ctrl1.discharge_off)
                        {

                            g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                            
                            sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                        }
                        else if( g_sys_pd_info.c1_attached_discharge_off_flag )
                        {
                            g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                            //sys_gpio_vbus_en_set(FALSE);
                            //dpm_vbus_source_en_set(TRUE);
                            if ((dpm_cable_detect_done_get()) && 
                                (dpm_current_pwr_mode_get()))
                            {
                                if (pe_pd_connected_get())
                                {
                                    dpm_hard_reset_req_set(TRUE);
                                    pe_state_machine();
                                }
                                else {
                                    dpm_vbus_source_en_set(TRUE);
                                }
                            }
                            
                        }
                    }
                    else
                    {
                        //sys_pd_cfg_src_power_profile_set(POWER_PROFILE_7P5W_FIXED);
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_gpio_usba_qc_on_set(FALSE); 
                        //sys_gpio_vbus_en_set(FALSE);
                        if(!g_sys_pd_info.c1_attached_discharge_off_flag)
                        {
                            dpm_vbus_source_en_set(FALSE);
                            g_sys_pd_info.c1_attached_discharge_off_flag = TRUE;

                        }
                        
                    } 
                }
            }
        }
        else 
        {
           
            if ((!dpm_cable_detect_done_get())&&((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.c1_conn_changed_tick) >= 20))
            {
                if(g_sys_pd_info.usba_no_current_flow_flag)
                {
                    C2_power_idx = POWER_PROFILE_45W_PPS;
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                }
                else
                {
                    if(sys_gpio_usba1_power_on_get()&&(g_sys_pd_info.c2_sta.conn))
                    {
                        C2_power_idx = POWER_PROFILE_45W_PPS;
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_45W_PPS);
                        sys_gpio_usba_qc_on_set(FALSE);
                    }        

                }
               
                if(g_sys_pd_info.c1_ctrl1.discharge_off)
                {

                    g_sys_pd_info.c1_ctrl1.discharge_off = FALSE;
                    
                    sys_control_1_reg_set((SYS_CONTROL_1_REG_t *)&(g_sys_pd_info.c1_ctrl1));

                }
                if( g_sys_pd_info.c1_attached_discharge_off_flag )
                {
                    g_sys_pd_info.c1_attached_discharge_off_flag = FALSE;
                    //sys_gpio_vbus_en_set(FALSE);

               }
            }
        }
    }

#if CLI_ENABLED
	    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2) 
        {
            printf("C1 pf=%u(%u),%u|%u|%u|%u, C2 %u|%u|%u\n",
                usbpd_cfg_port_src_fixed_pwr_prof_get(), 
                usbpd_cfg_port_src_pdp_get(),
                dpm_cable_detect_done_get(), 
                g_sys_pd_info.pd_power_nego_completed,
                g_sys_pd_info.c1_current_pwr,
                g_sys_pd_info.ibus_current,
                g_sys_pd_info.c2_sta.conn,
                g_sys_pd_info.c2_pd_sta.power_nego_completed,
                g_sys_pd_info.c2_current_pwr);
	    }
#endif /* CLI_ENABLED */
    if((!dpm_port_dead_battery_get())&&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m20c_otp_flag)&&
        (!g_sys_pd_info.usba_ocp_flag))
    {
        
        if((!dpm_cable_detect_done_get())&&(!g_sys_pd_info.c2_sta.conn)&&
            (!sys_gpio_usba_qc_on_get())&&(g_sys_pd_info.usba1_indet_flag))
        {

            sys_usba_restore();
            
            if (sys_cfg_dbg_get())
            {
                printf("usba on!");
            }
        }

    }
    
    if ((C2_power_idx != g_sys_pd_info.c2_power_profile)&&(C2_power_idx!=POWER_PROFILE_CUSTOMIZE_FIXED))
	{
		sys_src_pwr_profile_reg_set(C2_power_idx);
	    if (sys_cfg_dbg_get())
        {
            printf("C2 pf=%u,%u|%u|%u, C1 %u|%u|%u|%u\n", C2_power_idx, 
                g_sys_pd_info.c2_sta.conn,
                g_sys_pd_info.c2_pd_sta.power_nego_completed,
                g_sys_pd_info.c2_current_pwr,
                usbpd_cfg_port_src_fixed_pwr_prof_get(), 
                dpm_cable_detect_done_get(), 
                g_sys_pd_info.pd_power_nego_completed,
                g_sys_pd_info.c1_current_pwr);
	    }
	}

    // 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_pd_connected_get()))
        {
            dpm_source_cap_change_set(TRUE);
            dpm_hrst_due_to_no_current_flag_set(FALSE);
            if (pe_state_get() == PE_SRC_READY)
            {
                pe_state_machine();
            }
        }
        usbpd_cfg_port_src_fixed_pwr_prof_changed_flag_set(FALSE);
#if CLI_ENABLED
	    if (sys_cfg_dbg_get()) 
        {
            printf("C1 pf=%u(%u),%u|%u|%u|%u, C2 %u|%u|%u\n",
                usbpd_cfg_port_src_fixed_pwr_prof_get(), 
                usbpd_cfg_port_src_pdp_get(),
                dpm_cable_detect_done_get(), 
                g_sys_pd_info.pd_power_nego_completed,
                g_sys_pd_info.c1_current_pwr,
                g_sys_pd_info.ibus_current,
                g_sys_pd_info.c2_sta.conn,
                g_sys_pd_info.c2_pd_sta.power_nego_completed,
                g_sys_pd_info.c2_current_pwr);
	    }
#endif /* CLI_ENABLED */
    }
}
#endif /* (!SYS_POWER_POLICY_DISABLED) */


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_bat_vbat_fb_val_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)
        {
#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;
    }
}


#if 0
void sys_bat_capacity_check()
{
#if (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED)
	u8_t dpm_curr_idx = 0;
	u8_t dpm_curr_num = 0;
	u16_t (*p_curr_curve_arr)[SYS_NUM_OF_VBAT_SCALE];
	u8_t i = 0;
	u8_t indicator_curr;
#endif /* (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED) */

    if (dpm_cable_detect_done_get() || (g_sys_pd_info.c2_sta.conn))
    {
        if (sys_bat_current_ibat_val_get() > 300)
        {
            if (sys_bat_charging_flag_get())
            {
                if (sys_bat_current_ibat_val_get() > 2500)
                {
                    sys_bat_current_ibat_val_dec(380);
                }
                else {
                    sys_bat_current_ibat_val_dec(120);
                }
                
            }
            else {
                sys_bat_current_ibat_val_inc(230);
            }
        }
    }

#if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED
    // Capacity update
    sys_bat_cap_update();
#endif /* SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED */

#if (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED)
    sys_bat_accum_vbat_val_inc(sys_bat_current_vbat_val_get());
#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)
    {
#if (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED)
        sys_bat_avg_vbat_val_set(sys_bat_accum_vbat_val_get() / sys_bat_accum_val_index_get());
        sys_bat_accum_vbat_val_set(0);
#endif /* (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED) */
        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);

#if (!SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED)  /* modified by James Gan - 2018-11-19 */

#if CLI_ENABLED
    	//if (sys_cfg_dbg_get())  printf("capacity check, ");
#endif /* CLI_ENABLED */
    	if (sys_bat_charging_flag_get())
    	{
    		dpm_curr_num = SYS_NUM_OF_IBAT_SCALE_FOR_CHARGE;
    		p_curr_curve_arr = &charge_curr_curve[0];
#if CLI_ENABLED
    		//if (sys_cfg_dbg_get()) printf("charge mode.\n");
#endif /* CLI_ENABLED */
    	}
        else
    	{
    		dpm_curr_num = SYS_NUM_OF_IBAT_SCALE_FOR_DISCHARGE;
    		p_curr_curve_arr = &discharge_curr_curve[0];
#if CLI_ENABLED
    		//if (sys_cfg_dbg_get()) printf("discharge mode.\n");
#endif /* CLI_ENABLED */
    	}

    	if (sys_bat_avg_ibat_val_get() < (SYS_BAT_IBAT_CURRENT_0p5A))
    	{
    		dpm_curr_idx = 0;
    	}
    	else
    	{
    		dpm_curr_idx = (sys_bat_avg_ibat_val_get() - SYS_BAT_IBAT_CURRENT_0p5A) / SYS_BAT_IBAT_CURRENT_1A + 1;
    		if (dpm_curr_num <= dpm_curr_idx) dpm_curr_idx = (dpm_curr_num - 1);
    	}

        // capacity 100%
    	if (sys_bat_avg_vbat_val_get() >= sys_bat_max_rated_charge_volt_get())
    	{
            i = 100;
    	}
        // 80% - 99%
        else if (sys_bat_avg_vbat_val_get() >= p_curr_curve_arr[dpm_curr_idx][0])
    	{
    		i = 80 + sys_bat_ocv_rate(p_curr_curve_arr[dpm_curr_idx][0], sys_bat_max_rated_charge_volt_get(), 20);
    	}
        // 60% - 79%
        else if (sys_bat_avg_vbat_val_get() >= p_curr_curve_arr[dpm_curr_idx][1])
    	{
    		i = 60 + sys_bat_ocv_rate(p_curr_curve_arr[dpm_curr_idx][1], p_curr_curve_arr[dpm_curr_idx][0], 20);
    	}
        // 40% - 59%
        else if (sys_bat_avg_vbat_val_get() >= p_curr_curve_arr[dpm_curr_idx][2])
    	{
    		i = 40 + sys_bat_ocv_rate(p_curr_curve_arr[dpm_curr_idx][2], p_curr_curve_arr[dpm_curr_idx][1], 20);
        }
        // 20% - 39%
        else if (sys_bat_avg_vbat_val_get() >= p_curr_curve_arr[dpm_curr_idx][3])
    	{
    		i = 20 + sys_bat_ocv_rate(p_curr_curve_arr[dpm_curr_idx][3], p_curr_curve_arr[dpm_curr_idx][2], 20);
    	}
        // 0% - 19%
        else if (sys_bat_avg_vbat_val_get() >= SYS_BAT_DEAD_VOLT)
    	{
    		i = sys_bat_ocv_rate(SYS_BAT_DEAD_VOLT, p_curr_curve_arr[dpm_curr_idx][3], 20);
    	}
        else if (sys_bat_avg_vbat_val_get() < SYS_BAT_DEAD_VOLT)
        {
            i = 0;
        }

    	if (sys_bat_charging_flag_get())
    	{
            if (i > g_sys_pd_info.bat_cap_indicator_pre_charge)
    		{
    			g_sys_pd_info.bat_cap_indicator_pre_charge = i;
    			indicator_curr = i;
    		}
            else
    		{
    			indicator_curr = g_sys_pd_info.bat_cap_indicator_pre_charge;
    		}
    	}
        else
    	{
    		if (i < g_sys_pd_info.bat_cap_indicator_pre_discharge)
    		{
    			g_sys_pd_info.bat_cap_indicator_pre_discharge = i;
    			indicator_curr = i;
    		}
            else
    		{
    			indicator_curr = g_sys_pd_info.bat_cap_indicator_pre_discharge;
    		}
    	}

        if (sys_bat_capacity_get() != indicator_curr)
        {
            sys_bat_capacity_set(indicator_curr);
        }

#endif /* #if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED */

        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())
        {
#if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED  /* modified by James Gan - 2018-12-23 */
            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());
#else
            printf("ibat=%u,vbat=%u,cur=%u,i=%u,cur=%u,soc=%u\n", 
                sys_bat_avg_ibat_val_get(), sys_bat_avg_vbat_val_get(), dpm_curr_idx, 
                i, indicator_curr, sys_bat_capacity_get());
#endif /* #if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED */
    	}
#endif

        //sys_pd_power_policy_process(FALSE);
        sys_battery_cap_reg_set(sys_bat_capacity_get());
    }
}
#endif /* SYS_POWER_BANK_ENABLED */


#if SYS_LED_ENABLED

#if (!SYS_SMG_DISPLAY_ENABLED)  /* modified by James Gan - 2019-12-06 */
void sys_pd_init_display()
{
    static u8_t u8_num = 1, u8_direction = 0;

#if 0 /*CLI_ENABLED*/
	if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("Init..led %u\n", u8_num);
#endif
#if SYS_LED_C1_CTR
	sys_gpio_bat_cap_led_step_on(u8_num);
#else
    if(u8_num > 0)
    {
        g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(u8_num-1);
    }
    else
    {
        g_sys_pd_info.sys_led_bitmap = 0;

    }
    sys_led_bit_map_reg_set((u8_t*)&(g_sys_pd_info.sys_led_bitmap));
#endif
	
#if 1  /* deleted by James Gan - 2020-04-20 */
	if (0 == (g_sys_pd_info.continuous_timer_tick % 3))
#endif /* #if 0 */
	{
		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;
    }
}
#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  /* deleted by James Gan - 2020-04-20 */
	if (0 == (g_sys_pd_info.continuous_timer_tick % 3))
#endif /* #if 0 */
	{
        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;
    }
}
#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)))
            {
#if SYS_LED_C1_CTR           
                // turn on all LEDs
                sys_gpio_bat_cap_full_led_on();
#else
                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_5);
        
#endif
            }
            else {
#if SYS_LED_C1_CTR            
                sys_gpio_bat_cap_1st_led_on();
#else
                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);

#endif
            }
#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(g_sys_pd_info.led_breathing)
        {
            // do nothing
            if(sys_bat_capacity_get() >= 75)
            {
                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
            
            }
            else if(sys_bat_capacity_get() >= 50)
            {
                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_3);

            }
            else if(sys_bat_capacity_get() >= 25)
            {

                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_2);
            }
            else
            {
                g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);
            }

        }
        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 ((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging)
                {
                    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_C1_CTR                    
#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 */
#else
#if SYS_LED_DISPLAY_DURATION_ENABLED

                        g_sys_pd_info.sys_led_bitmap = 0;
#else
                        g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_5);
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */
                       
#endif
                         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))
                    {
#if SYS_LED_C1_CTR                    
                        sys_gpio_bat_cap_full_led_on();
#else
                        g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_5);
#endif
                    }
                    else {
#if SYS_LED_C1_CTR                    
                        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

                        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
                        {
                            
                            g_sys_pd_info.sys_led_bitmap= sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
                        }
                        else {
                            
                            g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_5);
                        }

#endif
                        
                    }
                }
                else {
#if SYS_LED_C1_CTR                
                    sys_gpio_bat_cap_full_led_on();
#else
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_5);
#endif
                }
            }
            else if (sys_bat_capacity_get() >= 60)
            {
#if SYS_LED_C1_CTR           
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (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 (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_3);
                }
                else {
              
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
                }

#endif
            }
            else if (sys_bat_capacity_get() >= 40)
            {
#if SYS_LED_C1_CTR            
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (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 (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_2);
                    
                }
                else {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_3);
                }
#endif
                
            }
            else if (sys_bat_capacity_get() >= 20)
            {
#if SYS_LED_C1_CTR          
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (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 (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);
                }
                else {
                   
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_2);
                }

#endif
                
            }
            else
            {
#if SYS_LED_C1_CTR           
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_led_off();
                }
                else {
                    sys_gpio_bat_cap_1st_led_on();
                }
#else
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    
                    g_sys_pd_info.sys_led_bitmap = 0;
                }
                else {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);
                }

#endif
            }
#else // 4 LEDs
            if (sys_bat_capacity_get() >= 75)
            {
                if ((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging)
                {
                    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_C1_CTR                     
#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 */
#else
#if SYS_LED_DISPLAY_DURATION_ENABLED
                        g_sys_pd_info.sys_led_bitmap = 0;
#else
                        g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
#endif /* SYS_LED_DISPLAY_DURATION_ENABLED */

#endif
                        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))
                    {
#if SYS_LED_C1_CTR                    
                        sys_gpio_bat_cap_full_led_on();
#else
                        g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
#endif
                    }
                    else {
#if  SYS_LED_C1_CTR                  
                        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
                        if (0 == (g_sys_pd_info.continuous_timer_tick % 10))
                        {
                            
                            g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_3);
                        }
                        else {
                            
                            g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
                        }

#endif
                        
                    }
                }
                else {
#if  SYS_LED_C1_CTR                 
                    sys_gpio_bat_cap_full_led_on();
#else
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);                    

#endif
                }
            }
            else if (sys_bat_capacity_get() >= 50)
            {
#if SYS_LED_C1_CTR           
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (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 (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_2);
                }
                else {
                   
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_3);
                }

#endif
                
            }
            else if (sys_bat_capacity_get() >= 25)
            {
#if  SYS_LED_C1_CTR          
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (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 (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);
                }
                else {
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_2);
                }

#endif
            }
            else
            {
#if SYS_LED_C1_CTR
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_gpio_bat_cap_led_off();
                }
                else {
                    sys_gpio_bat_cap_1st_led_on();
                }
#else
                if (((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {                    
                    g_sys_pd_info.sys_led_bitmap = 0 ;
                }
                else {                    
                    g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_1);
                }               

#endif                
            }
#endif /* #if (5==SYS_LED_NUM) */
#else
            if ((g_sys_pd_info.c1_ctrl.charge) || g_sys_pd_info.c2_sta.charging)
            {
                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 ((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 ((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 (!SYS_HUB_LED_ENABLED)
                if ((g_sys_pd_info.prevent_auto_poweroff) &&
                    (0 == (g_sys_pd_info.continuous_timer_tick % 10)))
                {
                    sys_smg_display_data_set(SMG_X);
                }
#endif /* (!SYS_HUB_LED_ENABLED) */
                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
#if SYS_LED_C1_CTR    // turn off all LEDs
        sys_gpio_bat_cap_led_off();
#else
        g_sys_pd_info.sys_led_bitmap = 0 ;
#endif
        
#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))) && 
        ((!g_sys_pd_info.c1_ctrl.charge) && (!g_sys_pd_info.c2_sta.charging)))
    {
        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)) && 
        ((!g_sys_pd_info.c1_ctrl.charge) && (!g_sys_pd_info.c2_sta.charging)))
    {
        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 (!SYS_HUB_LED_ENABLED)  /* modified by James Gan - 2020-05-06 */
                if (g_sys_pd_info.prevent_auto_poweroff)
                {
                    if(((!g_sys_pd_info.c1_ctrl.charge) && (!g_sys_pd_info.c2_sta.charging)))
                    {
                        g_sys_pd_info.display_state = TRUE;
                        g_sys_pd_info.led_breathing = TRUE;
                        g_sys_pd_info.c1_ctrl.low_current_mode = TRUE;
                        sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));

                    }
                    else
                    {
                        g_sys_pd_info.led_breathing = FALSE;
                        g_sys_pd_info.display_state = TRUE;
                        g_sys_pd_info.c1_ctrl.low_current_mode = FALSE;
                        sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));

                    }
                }
                else {
                    g_sys_pd_info.display_state = TRUE;
                }
#else
                g_sys_pd_info.display_state = TRUE;
#endif /* #if (!SYS_HUB_LED_ENABLED) */
                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();
#if (!SYS_LED_C1_CTR) 
    sys_led_bit_map_reg_set((u8_t*)&g_sys_pd_info.sys_led_bitmap);
#endif   
    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();
#if (!SYS_LED_C1_CTR)         
        sys_led_bit_map_reg_set((u8_t*)&g_sys_pd_info.sys_led_bitmap);
#endif        
        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
u32_t sys_usba1_vbus_get()
{
    if (sys_gpio_usba1_power_on_get())
    {
        return drv_adc_read_multi_avg(SYS_USBA1_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBA_VBUS_ADC_CONSTANT / ADC_REF_DIVISOR;
    }
    else {
        return 0;
    }
}

u32_t sys_usba2_vbus_get()
{
    if (sys_gpio_usba2_power_on_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;
    }
    else {
        return 0;
    }
}


void sys_usba_restore()
{
    if (!usbpd_cfg_port_usba_en_get())
        return;
#if 0
    if ((g_sys_pd_info.usba1_indet_flag)&&(g_sys_pd_info.usba2_indet_flag))
    {
        g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_flag;
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_flag;
        sys_gpio_usba1_insert_detect_clear();
        sys_gpio_usba2_insert_detect_clear();
        // disable a1 QC
        g_sys_pd_info.usba1_qc_en_flag = FALSE;
        // disable a2 QC
        g_sys_pd_info.usba2_qc_en_flag = FALSE;
#if SYS_QUICK_CHARGE_ENABLED
        sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba2_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.usba2_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
		if (sys_cfg_dbg_get()) printf("A1 A2 On\n");
#endif /* CLI_ENABLED */
        sys_gpio_usba1_insert_detect_pin_clear();
        //sys_gpio_usba2_insert_detect_pin_clear();
    }
    else if (g_sys_pd_info.usba2_indet_flag)
    {
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_flag;
        sys_gpio_usba2_insert_detect_clear();
        // enable a2 QC
        g_sys_pd_info.usba2_qc_en_flag = TRUE;
#if SYS_QUICK_CHARGE_ENABLED
        sys_gpio_usba_qc_on_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        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 QC On\n");
#endif /* CLI_ENABLED */
        //sys_gpio_usba2_insert_detect_pin_clear();
        sys_gpio_usba1_insert_detect_pin_set();
    }
#endif    
    if (g_sys_pd_info.usba1_indet_flag)
    {
        g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_flag;
        sys_gpio_usba1_insert_detect_clear();
        // enable a1 QC
        g_sys_pd_info.usba1_qc_en_flag = TRUE;
#if SYS_QUICK_CHARGE_ENABLED
        sys_gpio_usba_qc_on_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        sys_gpio_usba_qc_on_set(TRUE);
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba_dc_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 QC On\n");
#endif /* CLI_ENABLED */
        //sys_gpio_usba2_insert_detect_pin_set();
        sys_gpio_usba1_insert_detect_pin_clear();
    }
    else 
    {
        sys_gpio_usba1_insert_detect_pin_set();
        //sys_gpio_usba2_insert_detect_pin_set();
    }
}

void sys_usba_init()
{
    // read status reg
    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
#if 1

    if (sys_gpio_usba1_insert_detect_get())
    {
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba_dc_on_set(TRUE);
        delay(500);
        sys_gpio_usba1_power_on_set(FALSE);
        sys_gpio_usba_dc_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);
    }
#endif
    // read status reg again
    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.usba1_indet_current_flag = TRUE;
    if (g_sys_pd_info.usba1_indet_current_flag)
    {
        g_sys_pd_info.usba1_indet_flag = TRUE;
#if CLI_ENABLED
		if (sys_cfg_dbg_get()) printf("A1 in\n");
#endif /* CLI_ENABLED */
    }
#if 0
    g_sys_pd_info.usba2_indet_current_flag = sys_gpio_usba2_insert_detect_get();
    if (g_sys_pd_info.usba2_indet_current_flag)
    {
        g_sys_pd_info.usba2_indet_flag = TRUE;
#if CLI_ENABLED
		if (sys_cfg_dbg_get()) printf("A2 in\n");
#endif /* CLI_ENABLED */
    }
#endif
    sys_usba_restore();
}

bool_t sys_usba_power_over_check()
{
    if ((sys_gpio_usba1_power_on_get()) && 
        (sys_gpio_usba2_power_on_get()))
    {
        g_sys_pd_info.usba_pwr = g_sys_pd_info.usba2_vbus_val * g_sys_pd_info.usba_ibus_avg_val;
        if (g_sys_pd_info.usba_pwr >= SYS_USBA_MAX_POWER)
        {
#if USBPD_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get())  printf("\nUSBA OCP,N=%u,R=%u\n", SYS_USBA_MAX_POWER, g_sys_pd_info.usba_pwr);
#endif /* USBPD_DEBUG_ENABLED */
            return TRUE;
        }
        else 
        {
            return FALSE;
        }
    }
    else if ((sys_gpio_usba1_power_on_get()) && 
        (!sys_gpio_usba2_power_on_get()))
    {
        g_sys_pd_info.usba_pwr = g_sys_pd_info.usba_vbus_val * g_sys_pd_info.usba_ibus_avg_val;
        if (g_sys_pd_info.usba_pwr >= SYS_USBA_MAX_POWER)
        {
#if USBPD_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get())  printf("\nUSBA1 OCP,N=%u,R=%u\n", SYS_USBA_MAX_POWER, g_sys_pd_info.usba_pwr);
#endif /* USBPD_DEBUG_ENABLED */
            return TRUE;
        }
        else 
        {
            return FALSE;
        }
    }
    else if ((!sys_gpio_usba1_power_on_get()) && 
        (sys_gpio_usba2_power_on_get()))
    {
        g_sys_pd_info.usba_pwr = g_sys_pd_info.usba2_vbus_val * g_sys_pd_info.usba_ibus_avg_val;
        if (g_sys_pd_info.usba_pwr >= SYS_USBA_MAX_POWER)
        {
#if USBPD_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get())  printf("\nUSBA2 OCP,N=%u,R=%u\n", SYS_USBA_MAX_POWER, g_sys_pd_info.usba_pwr);
#endif /* USBPD_DEBUG_ENABLED */
            return TRUE;
        }
        else 
        {
            return FALSE;
        }
    }
    else 
    {
        g_sys_pd_info.usba_pwr = 0;
        return FALSE;
    }
}
#endif /* SYS_USBA_ENABLED */


#define IBUS_VSAFE5V_OVER_MAX   (3500U)
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))
    {
#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+500;
        }
        else {
            current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * current + SYS_POWER_BANK_CURRENT_COMPENSATION_2+500;
        }

        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;
    }
}

void sys_c2_cc_sta_check(void)
{
    *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
    sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
    if (g_sys_pd_info.c2_sta_prev.conn != g_sys_pd_info.c2_sta.conn)
    {
        g_sys_pd_info.c2_conn_changed_tick = g_sys_pd_info.continuous_timer_tick;
        g_sys_pd_info.c2_pd_sta_prev.power_nego_completed = g_sys_pd_info.c2_pd_sta.power_nego_completed;
        g_sys_pd_info.c2_pd_sta.power_nego_completed = FALSE;
        g_sys_pd_info.c2_current_pwr = 15;
#if CLI_ENABLED
        if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1)
        {
            printf ("C2 STA(%u|%u).\n",g_sys_pd_info.c2_sta_prev.conn,g_sys_pd_info.c2_sta.conn);
        }
#endif
        if (g_sys_pd_info.c2_sta.conn)
        {
            sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
            if((!dpm_cable_detect_done_get())&&(g_sys_pd_info.c2_sta.pr_mode))

            {
                g_sys_pd_info.c1_c2_insert_state = SYS_C2_FST_INSERT;

            }
            if (g_sys_pd_info.c2_sta.pr_mode)
            {
                sys_pd_power_policy_process(TRUE);
            }
        }
        if(!g_sys_pd_info.c2_sta.conn)
        {
        }
    }
}

//void sys_c2_cc_sta2_check(void)
//{
//    *(u8_t *)(&g_sys_pd_info.c2_sta2_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta2);
//    sys_control_0_reg_get((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c2_sta2));
   

//}


void sys_c2_pd_sta_check(void)
{
    g_sys_pd_info.c2_vbus_val = sys_vbus_val_get();
    g_sys_pd_info.c2_ibus_val = sys_ibus_val_get();
    g_sys_pd_info.c2_rated_vbus = 0;
    g_sys_pd_info.c2_rated_ibus = 0;

    if (g_sys_pd_info.c2_sta.conn)
    {   
        *(u8_t *)(&g_sys_pd_info.c2_pd_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_pd_sta);
        sys_pd_status_reg_get((SYS_PD_STATUS_REG_t *)&(g_sys_pd_info.c2_pd_sta));
        g_sys_pd_info.c2_current_pwr = sys_operating_pwr_reg_get();
    }
    else 
    {
        g_sys_pd_info.c2_pd_sta.conn = FALSE;
        g_sys_pd_info.c2_pd_sta.pdo_pos = 0;
        g_sys_pd_info.c2_pd_sta.power_nego_completed = 0;
        g_sys_pd_info.c2_current_pwr = 0;
    }
}
   
#if 0
void sys_charging_ctrl(void)
{
    if ((DPM_PORT_STATE_CHARGE == dpm_port_state_get()) && 
        (g_sys_pd_info.c2_sta.conn) &&
        (!g_sys_pd_info.c2_sta.pr_mode))
    {
        if ((g_sys_pd_info.c1_current_pwr > g_sys_pd_info.c2_current_pwr) && 
            (!g_sys_pd_info.c1_ctrl.charge))
        {
            g_sys_pd_info.c1_ctrl.charge = TRUE;
            sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
            // update C2 charging status
            *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
            sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
            sys_gpio_pstop_set(TRUE);
#if SYS_POWER_BANK_ENABLED
            sys_bat_charge_enable(TRUE);
#endif /* SYS_POWER_BANK_ENABLED */
        }
        else if ((g_sys_pd_info.c2_current_pwr >= g_sys_pd_info.c1_current_pwr) && 
            (g_sys_pd_info.c1_ctrl.charge) && 
            (!g_sys_pd_info.c2_sta.charging))
        {
            g_sys_pd_info.c1_ctrl.charge = FALSE;
            sys_gpio_pstop_set(FALSE);
            sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
            // update C2 charging status
            *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
            sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
        }
        else if (((g_sys_pd_info.c2_sta.charging) && 
            (g_sys_pd_info.c1_ctrl.charge)) || 
            ((!g_sys_pd_info.c2_sta.charging) && 
            (!g_sys_pd_info.c1_ctrl.charge)))
        {
            if (g_sys_pd_info.c1_current_pwr > g_sys_pd_info.c2_current_pwr)
            {
                g_sys_pd_info.c1_ctrl.charge = TRUE;
            }
            else {
                g_sys_pd_info.c1_ctrl.charge = FALSE;
            }
            sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
            // update C2 charging status
            *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
            sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
            if (g_sys_pd_info.c1_ctrl.charge)
            {
                sys_gpio_pstop_set(TRUE);
#if SYS_POWER_BANK_ENABLED
                sys_bat_charge_enable(TRUE);
#endif /* SYS_POWER_BANK_ENABLED */
            }
            else {
                sys_gpio_pstop_set(FALSE);
            }
        }
    }
    else if ((DPM_PORT_STATE_CHARGE != dpm_port_state_get()) && 
        (g_sys_pd_info.c2_sta.conn) &&
        (!g_sys_pd_info.c2_sta.pr_mode) && 
        (g_sys_pd_info.c1_ctrl.charge))
    {
        g_sys_pd_info.c1_ctrl.idle = TRUE;
        g_sys_pd_info.c1_ctrl.charge = FALSE;
        sys_gpio_pstop_set(FALSE);
        sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
        // update C2 charging status
        *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
        sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
    }
    else if ((DPM_PORT_STATE_CHARGE == dpm_port_state_get()) && 
        (!g_sys_pd_info.c2_sta.conn) && 
        (!g_sys_pd_info.c1_ctrl.charge))
    {
        g_sys_pd_info.c1_ctrl.charge = TRUE;
        sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
        // update C2 charging status
        *(u8_t *)(&g_sys_pd_info.c2_sta_prev) = *(u8_t *)(&g_sys_pd_info.c2_sta);
        sys_type_c_status_0_reg_get((SYS_TYPE_C_STATUS_0_REG_t *)&(g_sys_pd_info.c2_sta));
        sys_gpio_pstop_set(TRUE);
#if SYS_POWER_BANK_ENABLED
        sys_bat_charge_enable(TRUE);
#endif /* SYS_POWER_BANK_ENABLED */
    }
}
#endif
void sys_shutdown(void)
{
    // disable USB-A
    if (usbpd_cfg_port_usba_en_get())
    {
        sys_gpio_usba1_power_on_set(FALSE);
        sys_gpio_usba2_power_on_set(FALSE);
        sys_gpio_usba_dc_on_set(FALSE);
    }
    
    dpm_cc_state_release();
    dpm_cc_state_init();
    dpm_rp_rd_clear();

    //g_sys_pd_info.c1_ctrl.shutdown = TRUE;
    //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));

    sys_gpio_pstop_set(FALSE);
#if SYS_SC8706_USE_EN
    SYS_BAT_REG_FIELD_SET(CTRL_OPTION3_1_REG,EN_DCDC,FALSE);
#endif
    sys_gpio_vbus_en_set(TRUE);
    sys_pd_vbus_discharge_en_set(TRUE);
    rtc_delay_us(5000UL);
    while(!dpm_vbus_is_at_vsafe0v());
    
    sys_gpio_vbus_en_set(FALSE);
    sys_pd_vbus_discharge_en_set(FALSE);
    rtc_delay_us(5000UL);
    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));
}
#if 0
void sys_gpio_bat_cap_led_breath_control(u32_t bitmap, u32_t duty)
{
    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_1))
    {
        drv_pwm_duty_set3(DRV_PWM_CHN_2, duty);
        drv_pwm_en_set(DRV_PWM_CHN_2,TRUE);
    }
    else {
        drv_pwm_duty_set3(DRV_PWM_CHN_2, 0);
        drv_pwm_en_set(DRV_PWM_CHN_2,TRUE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_2))
    {
        drv_pwm_duty_set3(DRV_PWM_CHN_3, duty);
        drv_pwm_en_set(DRV_PWM_CHN_3,TRUE);
    }
    else {
        drv_pwm_duty_set3(DRV_PWM_CHN_3, 0);
        drv_pwm_en_set(DRV_PWM_CHN_3,TRUE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_3))
    {
        drv_pwm_duty_set3(DRV_PWM_CHN_0, duty);
        drv_pwm_en_set(DRV_PWM_CHN_0,TRUE);
    }
    else {
        drv_pwm_duty_set3(DRV_PWM_CHN_0, 0);
        drv_pwm_en_set(DRV_PWM_CHN_0,TRUE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_4))
    {
        drv_pwm_duty_set3(DRV_PWM_CHN_1, duty);
        drv_pwm_en_set(DRV_PWM_CHN_1,TRUE);
    }
    else {
        drv_pwm_duty_set3(DRV_PWM_CHN_1, 0);
        drv_pwm_en_set(DRV_PWM_CHN_1,TRUE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_5))
    {
        drv_pwm_duty_set3(DRV_PWM_CHN_4, duty);
        drv_pwm_en_set(DRV_PWM_CHN_4,TRUE);
    }
    else {
        drv_pwm_duty_set3(DRV_PWM_CHN_4, 0);
        drv_pwm_en_set(DRV_PWM_CHN_4,TRUE);
    }
}
#endif
void sys_pd_breath_led_display()
{
    static u8_t s_idx = 0, s_dir = 0;

    if ((g_sys_pd_info.display_state) && (g_sys_pd_info.led_breathing))
    {
        if (0 == s_dir)
        {
            //g_sys_pd_info.sys_led_bitmap = sys_gpio_bat_cap_led_bitmap(SYS_GPIO_BAT_CAP_LED_4);
            sys_led_bit_map_reg_set((u8_t*)&g_sys_pd_info.sys_led_bitmap);
            sys_led_pwmduty_reg_set((u8_t*)& s_idx);
            
            s_idx= s_idx + 5;
            
            if (100 == s_idx) s_dir = 1;
        }
        else {
            sys_led_bit_map_reg_set((u8_t*)&g_sys_pd_info.sys_led_bitmap);
            sys_led_pwmduty_reg_set((u8_t*)&s_idx);
            s_idx= s_idx - 5;
             
			if (0 == s_idx) s_dir = 0;
        }
    }
    else
    {
        s_idx = 0;
        s_dir = 0;
    }
}

void sys_upd2_state_check()
{
    sys_upd2_sta_reg_get((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd2_sta));
#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) 
    {
        printf("upd2_rate_pwr=%d\n",(u8_t)g_sys_pd_info.upd2_rate_pwr);
    }
#endif /* CLI_ENABLED */
}
#if 0
void sys_upd_ibat_max_check()
{
     u8_t ibat_val = 0;
     u16_t ibat_set = 0;
     
     sys_ibat_max_reg_get(ibat_val);

     if(ibat_val &&(dpm_cable_detect_done_get())&&
        (dpm_port_state_get() == DPM_PORT_STATE_CHARGE))
     {
        
        if(g_sys_pd_info.ibat_max != ibat_val)
        {
            g_sys_pd_info.ibat_max = ibat_val;
            
            ibat_set = ibat_val  * 100;
            
            if((!g_sys_pd_info.upd2_sta.connect)||((g_sys_pd_info.upd2_sta.connect)&&
                (!g_sys_pd_info.upd2_sta.charge)))
            {
                
                if( ibat_set >= SC881X_IBAT_SET_LIMIT)
                {
                    //SYS_BAT_REG_SET(IBAT_LIM_SET_REG, SYS_BAT_IBAT_LIM_VAL_TO_REG(SC881X_IBAT_SET_LIMIT));
                    ibat_set = SC881X_IBAT_SET_LIMIT;
                }
                g_sys_pd_info.charge_mode = SYS_C1_CHARGE_MODE;
            }
            else if((g_sys_pd_info.upd2_sta.connect)&&
                (g_sys_pd_info.upd2_sta.charge))
            {

                if( ibat_set >= (SC881X_IBAT_SET_LIMIT * 2))
                {
                    //SYS_BAT_REG_SET(IBAT_LIM_SET_REG, SYS_BAT_IBAT_LIM_VAL_TO_REG(SC881X_IBAT_SET_LIMIT));
                    ibat_set = SC881X_IBAT_SET_LIMIT;
                }
                else
                {

                    ibat_set = ibat_set >> 1;
                }
                g_sys_pd_info.charge_mode = SYS_C1_C2_CHARGE_MODE;
            }
                
            SYS_BAT_REG_SET(IBAT_LIM_SET_REG, (u8_t)SYS_BAT_IBAT_LIM_VAL_TO_REG(ibat_val));
        }
        else
        {
            if(g_sys_pd_info.charge_mode == SYS_C1_C2_CHARGE_MODE)
            {
                if((!g_sys_pd_info.upd2_sta.connect)||((g_sys_pd_info.upd2_sta.connect)&&
                (!g_sys_pd_info.upd2_sta.charge)))
                {
                    ibat_set = ibat_val  * 100;
                    
                    if( ibat_set >= SC881X_IBAT_SET_LIMIT)
                    {
                        ibat_set = SC881X_IBAT_SET_LIMIT;
                    }
                    
                    g_sys_pd_info.charge_mode = SYS_C1_CHARGE_MODE;
                    SYS_BAT_REG_SET(IBAT_LIM_SET_REG, (u8_t)SYS_BAT_IBAT_LIM_VAL_TO_REG(ibat_val));
                }
                   
            }
            else if(g_sys_pd_info.charge_mode == SYS_C1_CHARGE_MODE)
            {
               
                
                if((g_sys_pd_info.upd2_sta.connect)&&
                (g_sys_pd_info.upd2_sta.charge))
                {
                    ibat_set = ibat_val  * 100;
                    
                    if( ibat_set >= (SC881X_IBAT_SET_LIMIT * 2))
                    {
                        ibat_set = SC881X_IBAT_SET_LIMIT;
                    }
                    else
                    {

                        ibat_set = ibat_set >> 1;
                    }
                    g_sys_pd_info.charge_mode = SYS_C1_C2_CHARGE_MODE;
                    SYS_BAT_REG_SET(IBAT_LIM_SET_REG, SYS_BAT_IBAT_LIM_VAL_TO_REG(ibat_set));
                }
            }
        }
     }
          
#if CLI_ENABLED
     if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) 
     {
        printf("ibat_max=%d ma\n",((u8_t)g_sys_pd_info.upd2_rate_pwr *100));
     }
#endif /* CLI_ENABLED */
}
#endif
void sys_mcu_ctr_handler()
{
     sys_mcu_ctr_reg_get((SYS_MCU_CTR_REG_t* )&(g_sys_pd_info.mcu_ctr));

     if (g_sys_pd_info.mcu_ctr.offcharge)
     {
        if (dpm_cable_detect_done_get()&&
            (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(SC881X_IBUS_SET_LIMIT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                sys_gpio_pstop_set(FALSE);
            } 
        }
     }
     else
     {
        if (dpm_cable_detect_done_get() &&
            (dpm_port_state_get() == DPM_PORT_STATE_CHARGE))
        {
            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(SC881X_IBUS_SET_LIMIT_MIN);
                sys_bat_charging_current_reach_peak_flag_set(FALSE);
                sys_gpio_pstop_set(TRUE);
                g_sys_pd_info.charging_current_saved = 0;
            }
        }
        else
        {
            if (g_sys_pd_info.charging_current_saved)
            {
                g_sys_pd_info.charging_current_saved = 0;
            }
        }   
     }

     if (g_sys_pd_info.mcu_ctr.offdischarge)
     {
        if (dpm_cable_detect_done_get()&&
            (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE))
        {
            if (dpm_vbus_source_en_get())
            {
                dpm_vbus_source_en_set(FALSE);
            }
        }
     }
     else
     {
        if (dpm_cable_detect_done_get()&&
            (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE)&&
            (!dpm_port_dead_battery_get()))
        {
            
            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
            }
        }
    }
#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) 
    {
        printf("offdischarge=%d offcharge=%d\n",g_sys_pd_info.mcu_ctr.offdischarge,
            g_sys_pd_info.mcu_ctr.offcharge);
    }
#endif /* CLI_ENABLED */
}

void sys_power_state_check()
{
    sys_power_sta_reg_get((SYS_POWER_STA_REG_t *)&(g_sys_pd_info.sys_sta));
#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) 
    {
        printf("sys_sta=%x\n",(g_sys_pd_info.sys_sta));
    }
#endif /* CLI_ENABLED */
}


void sys_pd_idle_hook(u32_t arg)
{
    g_sys_pd_info.current_time = now();

    sys_tick_t start_time = now();

    if (g_sys_pd_info.hpd_detect_start_time && (!sys_gpio_hpd_out_detect())&&
        (g_sys_pd_info.current_time > g_sys_pd_info.hpd_detect_start_time)&&
        ((g_sys_pd_info.current_time - g_sys_pd_info.hpd_detect_start_time) > SYS_HPD_HOT_INSERT_DETECT_DURATION_MAX)&&
        (g_sys_pd_info.ufp_d_sta.hpd_sta))
    {
        // hdp lost 2s
        g_sys_pd_info.ufp_d_sta.hpd_sta = 0;
        g_sys_pd_info.ufp_d_sta.irq_hpd = 0;
        prl_msg_tx(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
        g_sys_pd_info.hpd_irq_cnt = 0;
    }
    if ((g_sys_pd_info.attention_req_flg == TRUE)&& (g_sys_pd_info.dp_mode_flg == TRUE)&&
        ( g_sys_pd_info.hpd_irq_cnt < 3))
    {
        g_sys_pd_info.attention_req_flg = FALSE;
        prl_msg_tx(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
        g_sys_pd_info.hpd_irq_cnt++;
    }
    else
    {
        g_sys_pd_info.attention_req_flg = FALSE;
    }
#if 0
    if ((g_sys_pd_info.aux_en_time) &&
        ((u32_t)(now()- g_sys_pd_info.aux_en_time) > 35000)&&
        (!sys_gpio_sbuon_get()))
        {
            sys_gpio_sbuon_set(true);
            sys_gpio_dps2_set(true);
            sys_gpio_dps1_set(true);
            g_sys_pd_info.aux_en_time = 0;
            printf("en sbu\n");
        }
#endif
    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 0
    if ((*(u8_t*)&(g_sys_pd_info.event1)) > 0)
    {
        if (g_sys_pd_info.event1.cc_changed)
        {
            sys_c2_cc_sta_check();
            g_sys_pd_info.event1.cc_changed = 0;
        }

        if (g_sys_pd_info.event1.pd_changed)
        {
            sys_c2_pd_sta_check();
            g_sys_pd_info.event1.pd_changed = 0;
        }
        // clean alert
        sys_event_1_reg_set((SYS_EVENT_1_REG_t *)&(g_sys_pd_info.event1));
    }
#endif 
    if ((g_sys_pd_info.dp_mode_flg )&&
        (g_sys_pd_info.attention_start_tick) && 
        (g_sys_pd_info.continuous_timer_tick > g_sys_pd_info.attention_start_tick) &&
        ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.attention_start_tick) > 10)&&
        (pe_state_get() == PE_SRC_READY) &&
        (dpm_ufp_mode_get()))
    {
        g_sys_pd_info.attention_start_tick = 0;
        prl_msg_tx(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
        drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, 0);
        drv_gpio_intr_en_set(SYS_IO_HPD_OUT, TRUE);
    }
    //handler QC state machine
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        if ((!pe_pd_connected_get()) &&
            (dpm_current_pwr_mode_get()) && 
            (DPM_QC_DISABLED != dpm_qc_state_get(&g_usbc_qc_info))&&
            (g_pe_info.caps_cnt >10))
        {
            dpm_qc_state_machine(&g_usbc_qc_info);
            if ((DPM_QC_SRC_CONNECTED <= dpm_qc_state_get(&g_usbc_qc_info)) && 
                (!sys_gpio_pd_qc_led_get()))
            {
                sys_gpio_pd_qc_led_on();
            }
        }
    }
#endif /* SYS_QUICK_CHARGE_ENABLED */

    // handle system process here per 100ms
    if (drv_timer_expired(&(g_sys_pd_info.continuous_timer)))
    {
        g_sys_pd_info.continuous_timer_tick++;

        if ((g_sys_pd_info.continuous_timer_tick > 25) &&(drv_gpio_en_get(UART_RXD))&&
            ((!dpm_cable_detect_done_get()) ||
             (sys_cfg_dbg_get())))
        {
            sys_gpio_uart0_enable();
        }

        if (g_sys_pd_info.sys_initializing)
	    {
#if SYS_LED_ENABLED  /* modified by James Gan - 2019-11-22 */
            sys_pd_init_display();
#else
            // system init 1.6 seconds for without initial display
            if (16 <= g_sys_pd_info.continuous_timer_tick)
            {
                g_sys_pd_info.sys_initializing = FALSE;
            }
#endif /* #if SYS_LED_ENABLED */
            /*
             * after system init, we need to:
             * 1) enable short foldback feature
             * 2) disabled charging auto-termination
             * 3) battery capacity calibration
             */
            if (!g_sys_pd_info.sys_initializing)
            {
                sys_bat_dis_foldback_set(FALSE);
                //sys_bat_dis_term_set(FALSE);
                sys_bat_dis_term_set(TRUE);

            }
        }
        else {
               
            // read status reg
            //sys_bat_status_reg_set(SYS_BAT_REG_GET(FAULTS_STATUS_REG));
            sys_bat_dc_sta_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 over voltage check
            if (dpm_source_ocp_flag_get() && dpm_vbus_source_en_get())
            {
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pd_qc_led_off();
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
                g_sys_pd_info.upd1_sta.ocp = TRUE;
#if (!UARt1_disable_set)
                sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
#endif
#if CLI_ENABLED
    			if (sys_cfg_dbg_get()) printf("OVP: %umV\n",dpm_vbus_volt_get());
#endif /* CLI_ENABLED */
            }

            if (dpm_cable_detect_done_get() && 
                (POWER_ROLE_SOURCE == dpm_current_pwr_mode_get()) && 
                (PE_SRC_READY == pe_state_get()) && 
                (g_sys_pd_info.dr_swap_cnt < 2) && 
                (!(dpm_drs_req_rejected_get()))&&
                (dpm_dfp_mode_get())
                /*((pe_ps_ready_start_time_get()) && 
                ((u32_t)(now() - pe_ps_ready_start_time_get()) > 2000000UL))*/)
            {
                if(0 == g_sys_pd_info.dr_swap_cnt)
                {
                    dpm_dr_swp_req_set(TRUE);
                    dpm_dr_swp_requested_flag_set( TRUE);
                    
                    if (sys_cfg_dbg_get()) printf("========DR swap requested, cnt=%bu.\n", g_sys_pd_info.dr_swap_cnt);
                    g_sys_pd_info.dr_swap_cnt++;
                }else if((1 == g_sys_pd_info.dr_swap_cnt) && (dpm_drs_req_rejected_get()))
                {
                    dpm_dr_swp_req_set(TRUE);
                    dpm_dr_swp_requested_flag_set( TRUE);
                    if (sys_cfg_dbg_get()) printf("========DR swap requested, cnt=%bu.\n", g_sys_pd_info.dr_swap_cnt);
                    g_sys_pd_info.dr_swap_cnt++;
                }
            }
            // 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()))
            {
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pd_qc_led_off();
                dpm_source_ocp_flag_set(TRUE);
                
#if (!UARt1_disable_set)
                g_sys_pd_info.upd1_sta.ocp = TRUE;
                sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
#endif
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            }

            sys_bat_vbat_update();

#if SYS_POWER_BANK_ENABLED
#if 0
            // Dead battery checking
            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)&&(sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT)))
            {
                sys_bat_dead_check_cnt_inc(1);
                if (sys_bat_dead_check_cnt_get() >= SYS_POWER_BANK_CHECK_DEAD_BATTERY_CNT)
                {
                    dpm_port_dead_battery_set(TRUE);
                    
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("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);
                    }

                    if (usbpd_cfg_port_usba_en_get())
                    {
                        // disable USB-A
                        sys_gpio_usba1_power_on_set(FALSE);
                        sys_gpio_usba2_power_on_set(FALSE);
                        sys_gpio_usba_dc_on_set(FALSE);
                    }
                     g_sys_pd_info.upd1_sta.deadbattery = TRUE;
#if (!UARt1_disable_set)
                    sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
#endif
                    //g_sys_pd_info.c1_ctrl.dead_battery = TRUE;
                    //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));

                    //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);
                }
            }
            else
            {
                sys_bat_dead_check_cnt_set(0);

            }
#endif
#endif /* SYS_POWER_BANK_ENABLED */
            if(g_sys_pd_info.cable_detect_done_pre != g_dpm_info.cable_detect_done)
            {
                g_sys_pd_info.c1_conn_changed_tick = g_sys_pd_info.continuous_timer_tick;
                g_sys_pd_info.cable_detect_done_pre = g_dpm_info.cable_detect_done;

            }

            // process every 200ms
            if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
            {
                // get ibat value
                g_sys_bat_info.current_ibat_val = sys_bat_ibat_val_get();
                g_sys_pd_info.upd1_real_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current/1000000;

                {
                    
#if 0//SYS_POWER_BANK_ENABLED
                    if (g_sys_pd_info.c1_ctrl.charge)
                    {
                        // C1 power
                        g_sys_pd_info.current_charging_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current;

                        // A port power
                        u32_t usba_pwr = g_sys_pd_info.usba_pwr * SYS_BAT_DISCHARGING_EFFICIENCY;

                        u32_t c2_pwr = 0;
                        if ((g_sys_pd_info.c2_sta.conn) && (g_sys_pd_info.c2_sta.pr_mode))
                        {
                            c2_pwr = g_sys_pd_info.c2_vbus_val * g_sys_pd_info.c2_ibus_val * SYS_BAT_DISCHARGING_EFFICIENCY;
                        }

                        // available charge power 
                        g_sys_pd_info.current_charging_pwr *= SYS_BAT_CHARGING_EFFICIENCY;

                        if (g_sys_pd_info.current_charging_pwr > (usba_pwr + c2_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.current_charging_pwr-(usba_pwr + c2_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 + c2_pwr) - g_sys_pd_info.current_charging_pwr) / sys_bat_current_vbat_val_get());
                        }
                    }
                    else if (g_sys_pd_info.c2_sta.charging)
                    {
                        // C2 power
                        g_sys_pd_info.current_charging_pwr = g_sys_pd_info.c2_vbus_val * g_sys_pd_info.c2_ibus_val;

                        g_sys_bat_info.current_ibat_val = g_sys_pd_info.current_charging_pwr / sys_bat_current_vbat_val_get();

                        // A port power
                        u32_t usba_pwr = g_sys_pd_info.usba_pwr * SYS_BAT_DISCHARGING_EFFICIENCY;

                        u32_t c1_pwr = 0;
                        if (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE)
                        {
                            c1_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current * SYS_BAT_DISCHARGING_EFFICIENCY;
                        }

                        // available charge power 
                        g_sys_pd_info.current_charging_pwr *= SYS_BAT_CHARGING_EFFICIENCY;

                        if (g_sys_pd_info.current_charging_pwr > (usba_pwr + c1_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.current_charging_pwr-(usba_pwr + c1_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 + c1_pwr) - g_sys_pd_info.current_charging_pwr) / sys_bat_current_vbat_val_get());
                        }
                    }
                    else {
                        if (dpm_cable_detect_done_get() && (g_sys_pd_info.c2_sta.conn))
                        {
                            g_sys_bat_info.current_ibat_val += (g_sys_pd_info.c2_vbus_val * g_sys_pd_info.c2_ibus_val + g_sys_pd_info.usba_pwr) / sys_bat_current_vbat_val_get();
                        }
                        else if (dpm_cable_detect_done_get())
                        {
                            g_sys_bat_info.current_ibat_val += g_sys_pd_info.usba_pwr / sys_bat_current_vbat_val_get();
                        }
                        else if (g_sys_pd_info.c2_sta.conn)
                        {
                            g_sys_bat_info.current_ibat_val = (g_sys_pd_info.c2_vbus_val * g_sys_pd_info.c2_ibus_val + g_sys_pd_info.usba_pwr) / sys_bat_current_vbat_val_get();
                        }
                        else 
                        {
                            g_sys_bat_info.current_ibat_val = g_sys_pd_info.usba_pwr / sys_bat_current_vbat_val_get();
                        }
                        sys_bat_charging_flag_set(FALSE);
                        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());
                            sys_bat_charging_full_flag_set(FALSE);
                            sys_bat_charging_full_tick_set(0);
                        }
                        if ((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR) || 
                            (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE) ||
                            ((g_sys_pd_info.c2_sta.conn) &&
                             (g_sys_pd_info.c2_sta.pr_mode)))
                        {
                            sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
                        }
                        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) && 
                            (!g_sys_pd_info.c2_sta.conn))
                        {
                            sys_bat_state_set(SYS_BAT_STATE_IDLE);
                        }
                    }
#endif /* #if SYS_POWER_BANK_ENABLED */

#if SYS_POWER_SOURCE_NO_CURRENT_HRST
                    if ((dpm_cable_detect_done_get()) && 
                        (dpm_current_pwr_mode_get()) && 
                        (pe_pd_connected_time_get()) && 
                        ((u32_t)(now() - pe_pd_connected_time_get()) > 5000000UL) &&
                        (!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
                    }
#endif /* SYS_POWER_SOURCE_NO_CURRENT_HRST */
                }

#if SYS_POWER_BANK_ENABLED
                // check capacity
                //sys_bat_capacity_check();
               // sys_bat_capacity_set(sys_battery_cap_reg_get());
#if (!UARt1_disable_set)
               g_sys_bat_info.capacity = sys_battery_cap_reg_get();
#endif
#endif /* SYS_POWER_BANK_ENABLED */
                
#if SYS_USBA_ENABLED
                g_sys_pd_info.usba_vbus_val = sys_usba1_vbus_get();
                g_sys_pd_info.usba2_vbus_val = sys_usba2_vbus_get();
                g_sys_pd_info.usba_ibus_accum_val += sys_usba_ibus_get();
                g_sys_pd_info.usba_ibus_accum_val_idx++;
#endif /* SYS_USBA_ENABLED */

                // power down detection 
#if SYS_POWER_BANK_POWER_DOWN_DETECT
                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_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();
                        }
                        // System shutdown
                        sys_shutdown();
                    }
                }
                else {
                    g_sys_pd_info.power_down_detect_last_state = 0;
                    g_sys_pd_info.power_down_detect_start_time = 0;
                }
#endif

#if SYS_USBA_ENABLED
                // usb-a current check
                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 (((sys_gpio_usba1_power_on_get()) && (g_sys_pd_info.usba_vbus_val >= SYS_USBA_VBUS_HAS_CURRENT_FLOW_THR)) ||
                        ((sys_gpio_usba2_power_on_get()) && (g_sys_pd_info.usba2_vbus_val >= SYS_USBA_VBUS_HAS_CURRENT_FLOW_THR)))
                    {
                        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
                    }
                    else 
                    {
                        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)
                        {
                            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;
                        }
                    }
                    
                    // auto power off
#if SYS_POWER_BANK_AUTO_POWER_DOWN_EN
                    if (usbpd_cfg_port_auto_power_down_get() && (!dpm_port_dead_battery_get()))
                    {
#if SYS_POWER_KEY_DOUBLE_CLICK_CTRL  /* modified by James Gan - 2019-01-15 */
        				if ((!dpm_cable_detect_done_get()) && 
                            (!g_sys_pd_info.c2_sta.conn) && 
                            (((FALSE == g_sys_pd_info.prevent_auto_poweroff) && (g_sys_pd_info.usba_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 ((g_sys_pd_info.usba_no_current_flow_flag) && 
                            (!g_sys_pd_info.c2_sta.conn) && 
                            (!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);
                                    // System shutdown
                                    sys_shutdown();
                                }
                            }
                        }
                        else {
                            g_sys_pd_info.auto_power_down_last_tick = 0;
                        }
                    }
#endif
                }
#endif
#if SYS_POWER_BANK_ENABLED
                // dead battery
                if (dpm_port_dead_battery_get())
                {
                    if (!pe_prs_in_prog_get())
                    {
                        /* Enable charging in non-PD mode, and clear dead battery flag */
                        if ((DPM_PORT_STATE_CHARGE == dpm_port_state_get()) && 
                            (((1 <= dpm_rx_src_cap_num_get()) && 
                            (dpm_rx_src_cap_max_power_get() >= DEFAULT_MIN_PD_POWER)) || 
                            (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);
                                //g_sys_pd_info.c1_ctrl.dead_battery = FALSE;
                                //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
                                g_sys_pd_info.upd1_sta.deadbattery = FALSE;
#if (!UARt1_disable_set)
                                sys_upd1_sta_reg_set((SYS_UPD_STA_REG_t *)&(g_sys_pd_info.upd1_sta));
#endif
                                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);
                                }
                            }
                        }
                    }
                    if ((g_sys_pd_info.c2_sta.conn) && (g_sys_pd_info.c2_sta.pr_mode == 0))
                    {
#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);
                        //g_sys_pd_info.c1_ctrl.dead_battery = FALSE;
                        //sys_control_0_reg_set((SYS_CONTROL_0_REG_t *)&(g_sys_pd_info.c1_ctrl));
                        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);
                        }
                    }
                    if(sys_bat_current_vbat_val_get() > 18500)
                    {
                        dpm_port_dead_battery_set(FALSE);
                        //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);
                        }


                    }
                }
#endif /* SYS_POWER_BANK_ENABLED */
            }

#if SYS_OVERTEMP_DECTION_ENABLED
            if ((!usbpd_cfg_port_otp_disabled_get()) && 
                (g_sys_pd_info.continuous_timer_tick & 3) == 0)
            {
#if SYS_OVERTEMP_C1_DECTION_EN           
                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;
                }
                sys_ntc_val_set((u16_t)(g_sys_pd_info.ntc_volt));
#else               
                //g_sys_pd_info.ntc_volt= sys_ntc_val_get();
                u32_t temp_red = sys_bms_temp_get();
                if(temp_red ==0)
                {
                    g_sys_pd_info.temp_current = -273;
                
                }
                else
                {
                    g_sys_pd_info.temp_current = 0.1f*temp_red-273.15f ;

                }
                
#endif                
                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;
                g_sys_pd_info.m20c_otp_pre_flag = g_sys_pd_info.m20c_otp_flag;
                
                if (g_sys_pd_info.temp_current!= -273)
                {
                    /** Temperature greater than 60C, disable charge and discharge */
                    if (g_sys_pd_info.temp_current >= 60)
                    {
                        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.temp_current);
#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(0);
                        }

#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_usba1_power_on_set(FALSE);
                        sys_gpio_usba2_power_on_set(FALSE);
                        sys_gpio_pd_qc_led_off();
                    }
                    else if (g_sys_pd_info.temp_current >= 45) /** 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 60-55C(%u)\n",g_sys_pd_info.temp_current);
#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(0);
                        }
                    }
                    else if (g_sys_pd_info.temp_current >= 40) /** Temperature greater than 45C, 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.temp_current);
#endif /* CLI_ENABLED */
                        }
                        if (g_sys_pd_info.m20c_otp_flag)
                        {
                            g_sys_pd_info.m20c_otp_flag = FALSE;
#if CLI_ENABLED
                			if (sys_cfg_dbg_get()) printf("DCHG:OTR -10C(%u)\n",g_sys_pd_info.temp_current);
#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.temp_current);
#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.temp_current >= 0) &&(g_sys_pd_info.temp_current <45))
                    {
                        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.temp_current);
#endif /* CLI_ENABLED */
                        }
                        if (g_sys_pd_info.m20c_otp_flag)
                        {
                            g_sys_pd_info.m20c_otp_flag = FALSE;
#if CLI_ENABLED
                			if (sys_cfg_dbg_get()) printf("DCHG:OTR -20C(%u)\n",g_sys_pd_info.temp_current);
#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 60-45C(%u)\n",g_sys_pd_info.temp_current);
#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 40-45C(%u)\n",g_sys_pd_info.temp_current);
#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 -20-0C(%u)\n",g_sys_pd_info.temp_current);
#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);
                            g_sys_pd_info.charging_current_saved = 0;
                        }
                    }
                    else if (g_sys_pd_info.temp_current < 0)
                    {
                        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 -20-0C(%u)\n",g_sys_pd_info.temp_current);
#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(0);
                        }
                    }
                    else if (g_sys_pd_info.temp_current < -20)
                    {
                        if (!g_sys_pd_info.m20c_otp_flag)
                        {
                            g_sys_pd_info.m20c_otp_flag = TRUE;
#if CLI_ENABLED
                			if (sys_cfg_dbg_get()) printf("DCHG:OTP -10C(%u)\n",g_sys_pd_info.temp_current);
#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(0);
                        }

#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_usba1_power_on_set(FALSE);
                        sys_gpio_usba2_power_on_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.m20c_otp_pre_flag)&& (!g_sys_pd_info.m20c_otp_flag))) && 
                        (!dpm_port_dead_battery_get()))
                    {
                        sys_usba_restore();
                        if ((dpm_cable_detect_done_get()) && 
                            (dpm_current_pwr_mode_get()))
                        {
                            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
                            }
                        }
                    }
                }
            }
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

#if SYS_POWER_BANK_ENABLED
            // Current compensation every 500ms
            if ((g_sys_pd_info.continuous_timer_tick % 5) == 0)
            {
                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)
                        {
                            sys_bat_discharge_vbus_ibus_set(vbus_cfg+500U,ibus_cfg);
                        }
                        else if (g_sys_pd_info.ibus_current >= 3200)
                        {
                            sys_bat_discharge_vbus_ibus_set(vbus_cfg+400U,ibus_cfg);
                        }
                        else if (g_sys_pd_info.ibus_current >= 2400)
                        {
                            sys_bat_discharge_vbus_ibus_set(vbus_cfg+300U,ibus_cfg);
                        }
                        else if (g_sys_pd_info.ibus_current >= 1600)
                        {
                            sys_bat_discharge_vbus_ibus_set(vbus_cfg+200U,ibus_cfg);
                        }
                        else if (g_sys_pd_info.ibus_current >= 800)
                        {
                            sys_bat_discharge_vbus_ibus_set(vbus_cfg+100U,ibus_cfg);
                        }
                        else
                        {
                        	sys_bat_discharge_vbus_ibus_set(vbus_cfg,ibus_cfg);
        				}
                    }
#endif /* SYS_VOLTAGE_COMPENSATION_ENABLED */
                }

#if SYS_LED_ENABLED
                // handle digit or led display
                sys_pd_display_state_machine();
    	        sys_pd_display_process();
#if (!SYS_LED_C1_CTR)
                if(!g_sys_pd_info.led_breathing)
                {
                    sys_led_bit_map_reg_set((u8_t*)&g_sys_pd_info.sys_led_bitmap); 

                }                              
#endif
                
#endif /* SYS_LED_ENABLED */
#if (!UARt1_disable_set) 
                sys_mcu_ctr_handler();                
#endif
            }
#endif /* SYS_POWER_BANK_ENABLED */

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

#if 0
                if ((((sys_bat_bms_charging_flag_get()) && 
                    (sys_bat_bms_charging_full_flag_get()))||
                    ((g_sys_bat_info.charging&&(sys_bat_current_vbat_val_get() > 17400))))&&
                    (sys_bat_capacity_get() >= 90) &&
                    (g_sys_bat_info.current_ibat_val < 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);
                }
#endif              
            
#if (!UARt1_disable_set)    
            sys_upd_ibat_max_check();

#endif
            }
#if SYS_USBA_ENABLED
            // usb-a insert detection
            if (usbpd_cfg_port_usba_en_get())
            {
#if SYS_OVERTEMP_DECTION_ENABLED
            	if ((!g_sys_pd_info.p60c_otp_flag) &&
                    (!g_sys_pd_info.m20c_otp_flag) && 
                    (!dpm_port_dead_battery_get()))
#else
                if (!dpm_port_dead_battery_get())
#endif
                {
                    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_usba1_insert_detect_pin_clear();
                            //sys_gpio_usba2_insert_detect_pin_clear();
                            // disable QC
                            g_sys_pd_info.usba1_qc_en_flag = FALSE;
                            g_sys_pd_info.usba2_qc_en_flag = FALSE;
                            sys_gpio_usba_qc_on_set(FALSE);
#if SYS_QUICK_CHARGE_ENABLED
                            sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
#if CLI_ENABLED
            	            if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("DCHG LI\n");
#endif /* CLI_ENABLED */
                            //sys_gpio_usba_dc_on_set(TRUE);
                            if (!g_sys_pd_info.usba_ocp_flag)
                            {
                                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 */
                                }
                                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 */
                                }
                            }
                            sys_gpio_usba_dc_on_set(TRUE);
                        }
                    }
                    else {
                        g_sys_pd_info.prevent_auto_poweroff_last_state = FALSE;
                    }

                    if ((!g_sys_pd_info.usba_ocp_flag) && (!(g_sys_pd_info.prevent_auto_poweroff))
                        &&(!((g_sys_pd_info.c1_attached_discharge_off_flag)&&(g_sys_pd_info.c2_sta.charging)))
                        &&(!((g_sys_pd_info.c1_ctrl1.discharge_off)&&(g_sys_pd_info.c1_ctrl.charge))))
                    {
                        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();
                                sys_gpio_usba1_power_on_set(TRUE);
                                sys_gpio_usba_dc_on_set(TRUE);
                                sys_gpio_usba1_insert_detect_pin_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;
                                if (g_sys_pd_info.usba2_qc_en_flag)
                                {
                                    // disable a2 QC
                                    g_sys_pd_info.usba2_qc_en_flag = FALSE;
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
                                else {
                                    // Enable a1 QC
                                    g_sys_pd_info.usba1_qc_en_flag = TRUE;
                                    sys_gpio_usba_qc_on_set(TRUE);
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
#if CLI_ENABLED
                    			if (sys_cfg_dbg_get()) drv_uart_puts("A1 indet");
#endif /* CLI_ENABLED */
                            }
                        }
#if 0
                        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_usba2_power_on_set(TRUE);
                                //sys_gpio_usba2_insert_detect_pin_clear();
                                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_qc_en_flag)
                                {
                                    // disable a1 QC
                                    g_sys_pd_info.usba1_qc_en_flag = FALSE;
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
                                else {
                                    // Enable a2 QC
                                    g_sys_pd_info.usba2_qc_en_flag = TRUE;
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
#if CLI_ENABLED
                    			if (sys_cfg_dbg_get()) drv_uart_puts("A2 indet");
#endif /* CLI_ENABLED */
                            }
                        }
#endif
                        if (((g_sys_pd_info.usba1_indet_flag) || (g_sys_pd_info.usba2_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))
                        {
                            if (g_sys_pd_info.usba1_indet_flag)
                            {
                                g_sys_pd_info.usba1_indet_flag = FALSE;
                                if (g_sys_pd_info.usba1_qc_en_flag)
                                {
                                    g_sys_pd_info.usba1_qc_en_flag = FALSE;
                                    sys_gpio_usba_qc_on_set(FALSE);
                                    
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
                                sys_gpio_usba_dc_on_set(FALSE);
                                sys_gpio_usba1_power_on_set(FALSE);
                                g_sys_pd_info.usba1_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
                            }
                            if (g_sys_pd_info.usba2_indet_flag)
                            {
                                g_sys_pd_info.usba2_indet_flag = FALSE;
                                if (g_sys_pd_info.usba2_qc_en_flag)
                                {
                                    g_sys_pd_info.usba2_qc_en_flag = FALSE;
                                    sys_gpio_usba_qc_on_set(FALSE);
                                    
#if SYS_QUICK_CHARGE_ENABLED
                                    sys_gpio_usba_qc_on_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
                                }
                                g_sys_pd_info.usba2_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
                                sys_gpio_usba2_power_on_set(FALSE);
                            }
                            sys_gpio_usba1_insert_detect_pin_set();
                            //sys_gpio_usba2_insert_detect_pin_set();
#if CLI_ENABLED
                			if (sys_cfg_dbg_get()) drv_uart_puts("USB-A Off");
#endif /* CLI_ENABLED */
                        }
                    }

                    if (sys_usba_power_over_check())
                    {
                        g_sys_pd_info.usba_ocp_flag = TRUE;
                        sys_gpio_usba1_power_on_set(FALSE);
                        sys_gpio_usba2_power_on_set(FALSE);
                        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, Off\n");
#endif /* CLI_ENABLED */
                    }
                }
            }
#endif
#if (!UARt1_disable_set)
            if((g_sys_pd_info.continuous_timer_tick % 12) == 0)
            {
                
                sys_upd2_state_check();

            }
            if((g_sys_pd_info.continuous_timer_tick % 30) == 0)
            {
                //sys_upd2_state_check();
                sys_upd1_real_pw_set((u8_t)g_sys_pd_info.upd1_real_pwr);
            }
            
#endif

#if (!SYS_POWER_POLICY_DISABLED)
            // Power policy check every 3000ms
            if ((g_sys_pd_info.continuous_timer_tick % 30) == 0)
            {
                sys_pd_power_policy_process(FALSE);
            }
#endif /* (!SYS_POWER_POLICY_DISABLED) */

            // C1 VBUS check
            if ((!usbpd_cfg_capture_mode_get()) && 
                (usbpd_cfg_port_vbus_check_get()) && 
                (!dpm_cable_detect_done_get()) && 
                (dpm_vbus_volt_get() > 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);
            }

            // VCONN Sourcing check
            if ((dpm_cable_detect_done_get()) && (usbpd_cfg_port_vconn_en_get()) && 
                (((VBUS_CURR_HANDLING_CAP_RESV == dpm_rx_vdm_ack_cable_vbus_curr_cap_get()) && 
                ((u32_t)(now() - dpm_cc_connection_changed_time_get()) > 10000000UL)) || 
                ((VBUS_CURR_HANDLING_CAP_RESV != dpm_rx_vdm_ack_cable_vbus_curr_cap_get())&& 
                ((u32_t)(now() - pe_pd_connected_time_get()) > 5000000UL))) && 
                (dpm_presently_vconn_source_get()))
            {
#if USBPD_DEBUG_ENABLED
        		if (usbpd_cfg_dbg_get()) drv_uart_puts("Turn off VCONN");
#endif /* CLI_ENABLED */
                if (dpm_vconn_en_cc1_get())
                    dpm_vconn_en_cc1_set(FALSE);
                if (dpm_vconn_en_cc2_get())
                    dpm_vconn_en_cc2_set(FALSE);
                dpm_presently_vconn_source_set(FALSE);
            }

        }

        // restart timer
        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_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 */

#if 0  /* deleted by James Gan - 2020-04-17 */
    // Change power policy here
    if (MSG_SOP_TYPE_SOPP == dpm_msg_sop_type_get())
    {
        sys_pd_power_policy_process(TRUE);
    }
#endif /* #if 0 */
}

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;
        //g_sys_pd_info.upd1_rate_pwr = volt * current / 1000000;
#if 0//(!UARt1_disable_set)
        sys_upd1_rate_pw_set((u8_t)g_sys_pd_info.upd1_rate_pwr);
#endif
    }
}

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

#if 0  /* deleted by James Gan - 2020-05-08 */
    if (dir == PRL_MSG_DIR_TX)
    {
        drv_uart_putstr("\nTX ");
    }
    else {
        drv_uart_putstr("\nRX ");
    }
#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 */
    if (dir == PRL_MSG_DIR_TX)
    {
        p_info->head.data_obj_num = 2;
        p_info->vdm_head.obj_pos = dpm_rx_vdm_req_mode_pos_get();
        p_info->val = *(u32_t*)&(g_sys_pd_info.ufp_d_sta);
    }
}
#define SYS_PD_STD_DP_SID              0XFF01

void sys_pd_prl_msg_tx_vdm_svid_spec_cmd_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 SPEC CMD");
        }
        else {
            drv_uart_putstr("\nRX SPEC CMD");
        }
    }
#endif /* CLI_ENABLED */
    UPD_DATA_MSG_VDM_SPECIFIC_t *p_vdm_specific = (UPD_DATA_MSG_VDM_SPECIFIC_t *)p_msg;

    if (dir == PRL_MSG_DIR_TX)
    {
        if ((p_vdm_specific->vdm_head.svid == SYS_PD_STD_DP_SID) &&
            (p_vdm_specific->vdm_head.cmd_type == UPD_VDM_MSG_CMD_RESPONDER_ACK))
        {
            switch(p_vdm_specific->vdm_head.command)
            {
                case UPD_VDM_MSG_CMD_SVID_SPECIFIC_CMD_START:
                    
                    g_sys_pd_info.ufp_d_sta.ufp_dfp_connect = 2;
                    g_sys_pd_info.ufp_d_sta.power_low = 0;
                    g_sys_pd_info.ufp_d_sta.dp_en = 1;
                    g_sys_pd_info.ufp_d_sta.multi_func = 1;
                    g_sys_pd_info.ufp_d_sta.usb_cfg_req = 0;
                    g_sys_pd_info.ufp_d_sta.dp_exit = 0; 
                    g_sys_pd_info.ufp_d_sta.hpd_sta = 0;
                    g_sys_pd_info.ufp_d_sta.irq_hpd = 0;                       
                    
                    p_vdm_specific->head.data_obj_num = 2;
                    p_vdm_specific->val = *(u32_t*)&(g_sys_pd_info.ufp_d_sta);
                    break;
                case UPD_VDM_MSG_CMD_SVID_SPECIFIC_CMD2:

                    g_sys_pd_info.dp_mode_flg = TRUE;
                    if (sys_gpio_hpd_out_detect())
                    {
                        g_sys_pd_info.attention_start_tick = g_sys_pd_info.continuous_timer_tick;
                        g_sys_pd_info.ufp_tx_attention_msg_cnt = 0;
                        g_sys_pd_info.ufp_d_sta.hpd_sta = 1;
                        g_sys_pd_info.ufp_d_sta.irq_hpd = 0; 
                    }
                    else{
                        // 使能 GPIO0 中断
                        drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, 1);
                        drv_gpio_intr_en_set(SYS_IO_HPD_OUT, TRUE);
                        sys_pd_hpd_start_time_set(now());
                    }
                    //g_sys_pd_info.aux_en_time = now();
                    break;
                default:
                    break;
            }
        }
    }
    else
    {
        //
    }
}

void sys_pd_prl_msg_init_vdm_spec_cmd_receive_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 DP CONFIG");
        }
        else {
            drv_uart_putstr("\nRX DP CONFIG");
        }
    }
#endif /* CLI_ENABLED */
    UPD_DATA_MSG_VDM_SPECIFIC_t *p_vdm_specific = (UPD_DATA_MSG_VDM_SPECIFIC_t *)p_msg;

    if (dir == PRL_MSG_DIR_RX)
    {
        if (p_vdm_specific->vdm_head.svid == SYS_PD_STD_DP_SID)
        {
            if (p_vdm_specific->vdm_head.command == UPD_VDM_MSG_CMD_SVID_SPECIFIC_CMD_START)
            {
                prl_msg_tx(VDM_SVID_SPECIFIC_ACK_CMD_MSG, dpm_msg_sop_type_get());

            }
            else if(p_vdm_specific->vdm_head.command == UPD_VDM_MSG_CMD_SVID_SPECIFIC_CMD2)
            {
                UPD_DATA_MSG_VDM_DP_CONFIG_VDO_t* dp_ufp_rx_cfg =(UPD_DATA_MSG_VDM_DP_CONFIG_VDO_t*)&(p_vdm_specific->val);
                if ((g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp & dp_ufp_rx_cfg->cfg_ufp_u_ass)&&
                    (dp_ufp_rx_cfg->select_cfg == 2))
                {
                    sys_gpio_dps2_set(true);
                    sys_gpio_dps1_set(true);
                    if (dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_C)
                    {
                        if (!dpm_orient_select_get())  //CC1
                        {
                            sys_gpio_mux1_sel_set(FALSE);
                            sys_gpio_mux2_sel_set(TRUE);
                            sys_gpio_xsd1_set(TRUE);
                            sys_gpio_xsd2_set(TRUE);
                        }
                        else   //CC2
                        {
                            sys_gpio_mux1_sel_set(TRUE);
                            sys_gpio_mux2_sel_set(FALSE);
                            sys_gpio_xsd1_set(TRUE);
                            sys_gpio_xsd2_set(TRUE);
                        }
                    }
                    else if (dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_D)
                    {
                        if (!dpm_orient_select_get())
                        {
                            sys_gpio_mux1_sel_set(FALSE);
                            sys_gpio_xsd1_set(TRUE);
                            sys_gpio_xsd2_set(FALSE);
                        }
                        else
                        {
                            sys_gpio_mux1_sel_set(TRUE);
                            sys_gpio_xsd1_set(TRUE);
                            sys_gpio_xsd2_set(FALSE);
                        }
                    }
                    else if(dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_E)
                    {

                    }
                    rtc_delay_us(300);
                    sys_gpio_sbuon_set(true);
                    prl_msg_tx(VDM_SVID_SPECIFIC1_ACK_CMD_MSG, dpm_msg_sop_type_get());
                }
                else{
                    prl_msg_tx(VDM_SVID_SPECIFIC1_NACK_CMD_MSG, dpm_msg_sop_type_get());
                }
            }
            else
            {
                //resv
            }
        }
    }
    else{

    }
}

void sys_pd_prl_msg_ack_vdm_spec_cmd_receive_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("ack_vdm_spec_cmd_receive:\n");
    }
#endif /* CLI_ENABLED */
}

void sys_pd_prl_msg_vdm_disc_mode_resp_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("disc_mode_resp:\n");
    }
#endif /* CLI_ENABLED */
    UPD_DATA_MSG_VDM_DISCOVER_MODE_t *P_VDM_DISCOVER_MODE = (UPD_DATA_MSG_VDM_DISCOVER_MODE_t *)p_msg;
    UPD_DATA_MSG_VDM_DP_CAPABILITIES_VDO_t* dp_cap = (UPD_DATA_MSG_VDM_DP_CAPABILITIES_VDO_t*)&P_VDM_DISCOVER_MODE->mode_vdo[0];
    if (dir == PRL_MSG_DIR_TX)
    {
        if (P_VDM_DISCOVER_MODE->vdm_head.svid == SYS_PD_STD_DP_SID)
        {
            P_VDM_DISCOVER_MODE->head.data_obj_num = 2;
            dp_cap->ufp_d_ass_supp = g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp;//SYS_DP_ASS_E;
            dp_cap->dfp_d_ass_supp  = g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp;
            dp_cap->dp_ver = 1;// dp1.3
            dp_cap->port_cap = 1;//ufp_d
            dp_cap->recp_indn = 0;//plug
        }
    }
    else
    {
        
    }
}
void sys_pd_prl_msg_vdm_exit_mode_req_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("disc_mode_resp:\n");
    }
#endif /* CLI_ENABLED */
    UPD_DATA_MSG_VDM_EXIT_MODE_t *P_VDM_EXIT_MODE = (UPD_DATA_MSG_VDM_EXIT_MODE_t *)p_msg;
    if (dir == PRL_MSG_DIR_RX)
    {
        if (P_VDM_EXIT_MODE->vdm_head.svid == SYS_PD_STD_DP_SID)
        {
            sys_gpio_sbuon_set(FALSE);
            g_sys_pd_info.dp_mode_flg = FALSE;
            sys_pd_hpd_start_time_set(0);
            dpm_vdm_ack_set(TRUE);
            dpm_vdm_nak_set(FALSE);
            dpm_mode_exited_set(TRUE);
        }
        else
        {
            dpm_vdm_ack_set(FALSE);
            dpm_vdm_nak_set(TRUE);
            dpm_mode_exited_set(FALSE);
        }
    }
    else
    {
        
    }
}
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);
    }
}
#if 0
void sys_gp_usbpd_prl_msg_vdm_disc_svid_req_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)
    {
        if (usbpd_cfg_port_vdm_modal_opr_supp_get())
        {
            dpm_vdm_ack_set(TRUE);
            dpm_vdm_nak_set(FALSE);
        }
        else 
        {
            dpm_vdm_ack_set(FALSE);
            dpm_vdm_nak_set(TRUE);
        }
        g_sys_pd_info.aux_en_time = now();
#if VENDOR_DEFINE_ACK_DELAY_ENABLED
                // to fix ellisys IOP issue
            rtc_delay_us(VENDOR_DEFINE_ACK_DELAY_TIME);
#endif /* VENDOR_DEFINE_ACK_DELAY_ENABLED */
    }
}
#endif
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;
    g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp = SYS_DP_ASS_D;//SYS_DP_ASS_C|SYS_DP_ASS_D;
    g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp = 0;

    sys_pd_led_state_set(SYS_PD_LED_STATE_ON);

#if SYS_QUICK_CHARGE_ENABLED
    sys_qc_init();
#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_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_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_req_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(vdm_disc_svid_req, (v_func_args_ptr_t)sys_gp_usbpd_prl_msg_vdm_disc_svid_req_hook);

    usbpd_prl_msg_hook_set(vdm_svid_spec_cmd, (v_func_args_ptr_t)sys_pd_prl_msg_tx_vdm_svid_spec_cmd_hook);
    usbpd_prl_msg_hook_set(vdm_spec_cmd_receive, (v_func_args_ptr_t)sys_pd_prl_msg_init_vdm_spec_cmd_receive_hook);
    usbpd_prl_msg_hook_set(vdm_spec_cmd_req, (v_func_args_ptr_t)sys_pd_prl_msg_ack_vdm_spec_cmd_receive_hook);
    usbpd_prl_msg_hook_set(vdm_disc_mode_resp, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_disc_mode_resp_hook);
    usbpd_prl_msg_hook_set(vdm_exit_mode_req, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_exit_mode_req_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);
}


