/**
 * \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 */
#include "sys_ex_mcu_ctr.h"
#include  "sys_alt_control.h"


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

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

volatile SYS_PD_INFO_t g_sys_pd_info;

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

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

#if  SYS_OVERTEMP_DECTION_ENABLED

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

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

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

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

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

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

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

#define DPM_TEMP_M10C_VOLT          (27931)

#define DPM_TEMP_INVALID_VOLT       (32600)

#endif /* SYS_OVERTEMP_DECTION_ENABLED */

#define sys_sc8815_current_min      (300)

#define  OPEN_DPDMSWAP  1


static u8_t alt_sink_int_flag = 0;

void  sys_gpio_sink_int_hangdler()
{


	 alt_sink_int_flag = 1;
	 drv_gpio_intr_polar_set(ALT_SINK_INT, 0); //低电平中断
	 drv_gpio_intr_en_set(ALT_SINK_INT, TRUE);
}



/*
 * 自定义配置数据
 * 飞标准
 */

extern void sys_pd_cfg_port_pwr_fixed_cap_set(volatile POWER_FIXED_t *fixed, u32_t volt, u32_t curr, u32_t pwm_duty);


void sys_alt_user_src_power_profile_set(u32_t index,u8_t cap_num)
{



#if 1

            if(g_sys_pd_info.alt_sink28v_cur == 0)
            {
            	if((g_sys_pd_info.alt_sink20v_cur == 0))
            	{

            		if(alt_dc_invol_get() < 16000)
            		{
            			sys_pd_cfg_src_power_profile_set(POWER_PROFILE_30W_FIXED);
            		}
            		else sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_FIXED);


            	}
            	else if(g_sys_pd_info.alt_sink20v_cur == 50)
            	{
            		sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_FIXED);
            	}
            	else
            	{
            		sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_FIXED);
            	}
            }
            else
            {

            	sys_pd_cfg_src_power_profile_set(POWER_PROFILE_140W_FIXED);
            }


#endif


}






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_i2c_int_handler()
{
    g_sys_pd_info.i2c_int_flag = TRUE;
#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
    {
        printf("uart1_int_flag=%d\n", g_sys_pd_info.i2c_int_flag);
    }                    
#endif


}



void sys_gpio_hpd_isr(u32_t arg)
{
    g_sys_pd_info.hpd_last_state = g_sys_pd_info.hpd_state;
    // 读当前值，0有效

#if CLI_ENABLED
    if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
    {
        printf("intro hdp \r\n");
    }
#endif



    g_sys_pd_info.hpd_state = alt_holdout_get();

    if (!g_sys_pd_info.hpd_state) // 如果是low
    {
        // 设置上升沿，触发下一次中断
        drv_gpio_intr_polar_set(DSVL_HPDOUT, 1);
        sys_pd_hpd_start_time_set(now());
    }
    else
    {
        // 设置下降沿，触发下一次中断
        sys_tick_t hpd_current_time = now();
        drv_gpio_intr_polar_set(DSVL_HPDOUT, 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_uplink_info_update()
{
	u32_t set_pos_state = POWER_PROFILE_100W_FIXED;
	u8_t alt_tmp_cur[8];
   // static u8_t up_onetime = 0;
    static u32_t cnt = 0;
#if 1
	 static u8_t state = 0;
	    switch (state)
	    {
	        case 0:
	        	if((PE_SRC_READY != pe_state_get())&&( alt_sink_int_flag) )
	        	{

	        		state = 1;

	        		alt_sink_int_flag = 0;
	        		if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
	        		{
	        		    printf("alt_sink_int_flag\r\n");
	        		}

	        	}
	        	else if(PE_SNK_READY == pe_state_get()) //PE_SRC_READY != pe_state_get())
	        	{


	        		  if(alt_dc_invol_get() > 18000)
	        	     {
	        			 cnt ++;
	        			 if(cnt > 60)
	        			 {
	        				 cnt = 0;
							 state = 1;

							  alt_sink_int_flag = 0;
							  if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
							  {
								printf("dc vol%d\r\n",alt_dc_invol_get());
							  }
	        			 }

	        	    }
	        		else cnt = 0;
	        	}
	        	else
	        	{

	        		   state = 0;
	        		   cnt = 0;
	        	}

	           //   sys_pdo_info_reg_get();
	           // state = 1;
	            break;
	        case 1:

				alt_sink_curcap_get(alt_tmp_cur,6);  /*对着协议*/

				if(alt_tmp_cur[0] ==  I2C_ACK_DAT)
				{

				  g_sys_pd_info.alt_sink12v_cur = alt_tmp_cur[1];
				  g_sys_pd_info.alt_sink15v_cur = alt_tmp_cur[2];
				  g_sys_pd_info.alt_sink20v_cur = alt_tmp_cur[3];
				  g_sys_pd_info.alt_sink28v_cur = alt_tmp_cur[4];
				  g_sys_pd_info.alt_sink_maxpos = alt_tmp_cur[5];

				}
				else
				{
					g_sys_pd_info.alt_sink28v_cur = 0;
					g_sys_pd_info.alt_sink20v_cur = 30;  //出错默认3A
				}


				sys_alt_user_src_power_profile_set(set_pos_state,g_sys_pd_info.alt_sink_maxpos);



					 dpm_source_cap_change_set(TRUE);
					 dpm_hrst_due_to_no_current_flag_set(FALSE);

					state = 2;

				if((alt_tmp_cur[5] == 0 )&&(alt_dc_invol_get() < 10000))
				{
					state = 3;

				}
	            break;
	        case 2:

#if 1
			    if ((1) &&
					(dpm_cable_detect_done_get()) &&
					(POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get()))
				{
					if ( (pe_state_is_snk_rdy() ) &&
						(!dpm_pr_swp_requested_flag_get()))

					{

                              //|| (PE_UFP_VDM_GET_SVID == pe_state_get())
						if (drv_timer_stopped(&(g_dpm_info.pr_swp_request_timer)) &&
												!drv_timer_expired(&(g_dpm_info.pr_swp_request_timer)))
						   {
							   drv_timer_start(T_PR_SWP_REQUEST_TIMER,
								&(g_dpm_info.pr_swp_request_timer), NULL);
						  }


					}


			  }
			  if (drv_timer_expired(&(g_dpm_info.pr_swp_request_timer)))
			  {
				 state = 3;
				 if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1)
				 {
				   printf("into prswap\r\n");
				 }

				 dpm_pr_swp_req_set(TRUE);
				 dpm_pr_swp_requested_flag_set(TRUE);
			  }

#endif

	        	   // dpm_pr_swp_req_set(TRUE);
	        	   // dpm_pr_swp_requested_flag_set(TRUE);
	           // sys_max_pwr_get();
	             // state = 3;
	            break;
	        case 3:


	           state = 0;
	            break;
	        default:
	            break;
	    }


#endif


}
#define USB_UART_SINKDEBUG_OFF 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);
#if USB_UART_SINKDEBUG_OFF
        sys_gpio_uart0_enable_set(TRUE);

#endif
    }
    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 {

#if USB_UART_SINKDEBUG_OFF
            sys_gpio_uart0_enable_set(TRUE);

#endif
        }
    }
#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 */
   /* u32_t vbus = sys_bat_vbus_fb_val_get();
    if(vbus > VBUS_VSAFE0V_MAX_VOLT)
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_pd_vbus_discharge_en_set(TRUE);
        delay_ms(100);
        vbus = sys_bat_vbus_fb_val_get();
        if(vbus > 4000)
        {
            delay_ms(100);

        }   
    }*/

    sys_pd_vbus_discharge_en_set(FALSE);
#if SYS_POWER_BANK_ENABLED
    sys_bat_charge_enable(FALSE);
#endif

    sys_gpio_vbus_en_set(FALSE);
    sys_alt_led_on(FALSE);
   // alt_output_enable(TRUE);

    sys_alt_vbus_c1en(FALSE);


  //  sys_gpio_pmic_pstop_set(FALSE);
    sys_pd_power_policy_process(FALSE);
    sys_gpio_pd_qc_led_off();
    g_sys_pd_info.usbc_src_current_ocp_flg= FALSE;
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;
    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;

    g_sys_pd_info.switch_games_mode = FALSE;
    g_sys_pd_info.attention_start_tick = 0;
    g_sys_pd_info.dr_swap_cnt = 0;
}

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

#if USB_UART_SINKDEBUG_OFF
        sys_gpio_uart0_enable_set(FALSE);
#endif

#if 0
        if (!dpm_port_dead_battery_get())
        {
            // No need to enable QC sink
            dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
        }
#endif
    }
    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 */
#if 0
    if(g_sys_pd_info.usbc_power_ctrl_en)
    {
        if(!g_sys_pd_info.mcu_state.charge_en)
        {
            *(u8_t *)(&g_sys_pd_info.mcu_state) = dpm_ex_pw_ctrl_get();

        }
        if(g_sys_pd_info.mcu_state.charge_en)
        {
            sys_gpio_vbus_en_set(TRUE);
            sys_gpio_pmic_pstop_set(TRUE);
            sys_bat_charge_enable(TRUE);
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;

        }

    }
    else
#endif
    {

        sys_gpio_pmic_pstop_set(TRUE);
#if 0
        sys_bat_charge_enable(TRUE);
#endif
        dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
    }




    //alt_output_enable(FALSE);
    sys_alt_led_on(TRUE);

    //sys_alt_vbus_c1en(TRUE);



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

status_t sys_pd_sink_transit_to_new_power_hook()
{
    if (dpm_current_pwr_mode_get())
        return S_ERROR;

    if (!dpm_src_obj_pos_get())
        return S_ERROR;

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

        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);

        }
    }
    else
#endif
    {
#if SYS_POWER_BANK_ENABLED
        sys_bat_charge_enable(TRUE);
#endif
    }
    //sys_gpio_pd_qc_led_on();
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */

    return S_OK;
}

void sys_pd_source_unattached_hook()
{
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
        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 */
    /*u32_t vbus = sys_bat_vbus_fb_val_get();
    if(vbus > VBUS_VSAFE0V_MAX_VOLT)
    {
        sys_gpio_vbus_en_set(TRUE);
        sys_pd_vbus_discharge_en_set(TRUE);
        delay_ms(100);
        vbus = sys_bat_vbus_fb_val_get();
        if(vbus > 4000)
        {
            delay_ms(100);

        }   
    }*/
    sys_pd_vbus_discharge_en_set(FALSE);
#if SYS_POWER_BANK_ENABLED
    sys_bat_charge_enable(FALSE);
#endif



    alt_outputvol(0);
    sys_pd_vbus_discharge_en_set(TRUE);
    sys_gpio_vbus_en_set(FALSE);
   // sys_gpio_pmic_pstop_set(FALSE);
   // sys_pd_power_policy_process(FALSE);
   // sys_gpio_pd_qc_led_off();


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

    g_sys_pd_info.usbc_src_current_ocp_flg= FALSE;
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;
    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
    //g_sys_pd_info.ocp_restore_cnt = 0;
    g_sys_pd_info.switch_games_mode = FALSE;
    g_sys_pd_info.attention_start_tick = 0;
    g_sys_pd_info.dr_swap_cnt = 0;
}

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

void sys_pd_source_attached_hook()
{
#if SYS_QUICK_CHARGE_ENABLED
    if (usbpd_cfg_port_quick_charge_en_get())
    {
        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 0
    if(g_sys_pd_info.usbc_power_ctrl_en)
    {
        if(!g_sys_pd_info.mcu_state.discharge_en)
        {
            *(u8_t *)(&g_sys_pd_info.mcu_state) = dpm_ex_pw_ctrl_get();
            
        }
        if(g_sys_pd_info.mcu_state.discharge_en)
        {
            sys_gpio_vbus_en_set(TRUE);
            sys_gpio_pmic_pstop_set(TRUE);
            //g_sys_pd_info.vbus_source_en = TRUE;
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;
        }
        else
        {
            sys_gpio_vbus_en_set(FALSE);
            sys_gpio_pmic_pstop_set(FALSE);
            dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
            //g_sys_pd_info.vbus_source_en = FALSE

        }
    }
    else
#endif
    {
         //sys_gpio_vbus_en_set(TRUE);
         //sys_gpio_pmic_pstop_set(TRUE);
         dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;

    }
    sys_pd_vbus_discharge_en_set(FALSE);

    //alt_output_enable(TRUE);

    sys_gpio_vbus_en_set(TRUE);
    g_sys_pd_info.rated_vbus = VSAFE_5V,
    g_sys_pd_info.rated_ibus = 3000;
   /* if (!dpm_port_dead_battery_get())
    {
        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
    }
    else {
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
    }*/
   // sys_pd_power_policy_process(TRUE);
  //  sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
#if SYS_OVERTEMP_DECTION_ENABLED
    g_sys_pd_info.charging_current_saved = 0;
#endif /* SYS_OVERTEMP_DECTION_ENABLED */
}

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 */




    alt_outputvol(pos);   //进入调节电源--5 9 12 15 20 28


    if (POWER_SUPPLY_TYPE_PPS == usbpd_cfg_port_src_pwr_supply_type_get(pos))
    {
        
        if (usbpd_cfg_port_src_pps_type_get(pos))
        {
            current = usbpd_cfg_port_src_avs_pwr_max_pdp_get(pos) * 1000000 / usbpd_cfg_port_src_avs_pwr_max_volt_get(pos);
            voltage = REQ_PPS_OUTPUT_VOLT_GET(dpm_current_rdo_get())*VOLTAGE_AVS_REQ_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
        }
        else
        {
            current = usbpd_cfg_port_src_pps_pwr_max_curr_get(pos)*CURRENT_PPS_DIV;
            voltage = REQ_PPS_OUTPUT_VOLT_GET(dpm_current_rdo_get())*VOLTAGE_PPS_REQ_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
        }
        //current = REQ_PPS_OPR_CURR_GET(dpm_current_rdo_get())*CURRENT_PPS_DIV;   
    }
    else 
    {
        current = usbpd_cfg_port_src_fixed_pwr_curr_cap_get(pos)*CURRENT_DIV;
        voltage = usbpd_cfg_port_src_fixed_pwr_volt_cap_get(pos)*VOLTAGE_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
           
    }
    if(!pe_hard_reset_in_prog())
    {
        //g_sys_pd_info.vbus_set_volt = voltage;
        //g_sys_pd_info.ibus_set_curr = current;
        g_sys_pd_info.rated_vbus = voltage,
        g_sys_pd_info.rated_ibus = current;
       
    }
    
    if (current >= CURRENT_3000mA) 
    {
        current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO * current + SYS_POWER_BANK_CURRENT_COMPENSATION;
        
    }
    else {
        current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * current + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
    }
    
   // sys_bat_discharge_vbus_ibus_set(voltage, current, OUT_DIR);

    dpm_pe_rxmsg_ind_set(FALSE);
    dpm_pe_rxmsg_type_set(0);
    //系统接入口  …………………………
    //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)
{
    g_sys_pd_info.vbus_source_en = flg ;




    if (flg)
    {

    	sys_alt_vbus_c1en(FALSE);  /* 这个跟vbus对冲，关闭*/
        sys_gpio_vbus_en_set(TRUE);


    }
    else
    {

       sys_gpio_vbus_en_set(FALSE);



    }
}

bool_t sys_usbc_vbus_get()
{
    return (drv_adc_read_multi_avg(SYS_USBC_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBC_VBUS_ADC_CONSTANT )>>12;
}







#if 0
u16_t sys_adc_vbat_get()
{
    return (drv_adc_read_multi_avg(SYS_USBC_VBAT_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBC_VBUS_ADC_CONSTANT )>>12;
}
#endif

bool_t sys_pd_vbus_discharge_en_get(void)
{
#if 0
    return dpm_vbus_discharge_get();
#else
    return sys_gpio_vbus_discharge_en_get();
#endif
}

void sys_pd_vbus_discharge_en_set(bool_t flg)
{
#if 0
    dpm_vbus_discharge_set(flg);
#else
    sys_gpio_vbus_discharge_en_set(flg);
#endif
}

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

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

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

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

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

}

void sys_pd_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 */

}

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)
{
    if (sys_bat_capacity_get() >= 20)
    {
        g_sys_pd_info.previous_profile = usbpd_cfg_port_src_fixed_pwr_prof_get();
#if 0
       // 
        if (((pe_pd_connected_time_get()) && 
            ((u32_t)(now() - pe_pd_connected_time_get()) > 1000000UL)) || 
            (change_asap))
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
                if(dpm_cbl_plug_detected_get()&&(VBUS_CURR_HANDLING_CAP_5A == dpm_rx_vdm_ack_cable_vbus_curr_cap_get()))
                {
                    if((POWER_PROFILE_100W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get()))
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_PPS);
                    }
                }
                else {
                    if (POWER_PROFILE_60W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                    {
                        sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_PPS);
                    }
                }
            }
        }
        else if (!dpm_cable_detect_done_get()) 
        {
            if (POWER_PROFILE_60W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_PPS);
            }
            
        }
#else
        if (pe_pd_connected_get() || change_asap)
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
                if (POWER_PROFILE_140W_AVS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                {
                    usbpd_cfg_port_epr_mode_en_set(TRUE);
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_140W_AVS);
                }
            }
            else if(POWER_MODE_SINK == dpm_current_pwr_mode_get())
            {
                if (usbpd_cfg_port_epr_mode_en_get())
                {
                    usbpd_cfg_port_epr_mode_en_set(TRUE);
                }
            }
        }
        else if(!dpm_cable_detect_done_get())
        {
            if (POWER_PROFILE_140W_AVS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                usbpd_cfg_port_epr_mode_en_set(TRUE);
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_140W_AVS);
            }
        }
#endif
    }
    else
    {
#if 0
        //g_sys_pd_info.previous_profile = usbpd_cfg_port_src_fixed_pwr_prof_get();
        if (((pe_pd_connected_time_get()) && 
            ((u32_t)(now() - pe_pd_connected_time_get()) > 1000000UL)) || 
            (change_asap))
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
               
                if (POWER_PROFILE_60W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                {
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_PPS);
                }
               
              
            }
            else {
				 if((!g_sys_pd_info.usba_no_current_flow_flag)&&(!g_sys_pd_info.usbc2_no_current_flow_flag))
                 {
                    if((g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current)< 40000000)
                        {
                        sys_gpio_usba_c2_enble_set(FALSE);
                        
                    }
                    
                 } 
                 else if((!g_sys_pd_info.usba_no_current_flow_flag)||(!g_sys_pd_info.usbc2_no_current_flow_flag))
                 {
                    if((g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current)< 18000000)
                        {
                        sys_gpio_usba_c2_enble_set(FALSE);
                        
                    }
                    
                 }
            }
        }
        else if (!dpm_cable_detect_done_get()) 
        {
            if (POWER_PROFILE_60W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_60W_PPS);
            }
        }
#else
        if (pe_pd_connected_get() || change_asap)
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
#if 0
                if (dpm_port_epr_mode_get())
                {
                    dpm_epr_mode_exit_req_set(TRUE);
                }
#endif
                usbpd_cfg_port_epr_mode_en_set(FALSE);
                if (POWER_PROFILE_100W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
                {
                    sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_PPS);
                }
            }
        }
        else if(!dpm_cable_detect_done_get())
        {
            usbpd_cfg_port_epr_mode_en_set(TRUE);
            if (POWER_PROFILE_100W_PPS != usbpd_cfg_port_src_fixed_pwr_prof_get())
            {
                sys_pd_cfg_src_power_profile_set(POWER_PROFILE_100W_PPS);
            }
        }
#endif
    }

    // Change C1 power
    if (usbpd_cfg_port_src_fixed_pwr_prof_changed_flag_get()) 
    {
        if ((dpm_cable_detect_done_get()) && 
            (dpm_current_pwr_mode_get()) &&
            ((pe_state_get() == PE_SRC_READY)||
            (dpm_port_epr_mode_get())))
        {
#if 1       
#if 0  /* modified by James Gan - 2019-12-19 */
            if ((dpm_partner_prod_type_get() == UPD_PRODUCT_HUB)||
                (dpm_partner_prod_type_get() == UPD_PRODUCT_AMA))
            {
                dpm_source_cap_change_set(TRUE);
                dpm_hrst_due_to_no_current_flag_set(FALSE);
            }
            else {
                dpm_hard_reset_req_set(TRUE);
            }
#else
           // if(g_sys_pd_info.previous_profile == POWER_PROFILE_100W_FIXED)
           // {
           //     dpm_hard_reset_req_set(TRUE);
           // }
           // else{
           //     dpm_source_cap_change_set(TRUE);
           //     dpm_hrst_due_to_no_current_flag_set(FALSE);
           // }
           if (!dpm_port_epr_mode_get())
           {
                dpm_source_cap_change_set(TRUE);
                dpm_hrst_due_to_no_current_flag_set(FALSE);
           }
           else
           {
                dpm_hard_reset_req_set(TRUE);
           }
            
         
#endif /* #if 0 */
            pe_state_machine();
#else
            pe_error_recovery_directed_set(TRUE);
#endif
        }
        usbpd_cfg_port_src_fixed_pwr_prof_changed_flag_set(FALSE);
#if CLI_ENABLED
	    if (sys_cfg_dbg_get() >= SYS_DEBUG_LEVEL_2) printf("C1 pf=%u, cap=%u\n", usbpd_cfg_port_src_fixed_pwr_prof_get(), sys_bat_capacity_get());
#endif /* CLI_ENABLED */
    }
}
#endif /* (!SYS_POWER_POLICY_DISABLED) */



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)
        {
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_ERR_SET;
#if CLI_ENABLED
			if (sys_cfg_dbg_get()) drv_uart_puts("I2C Fault");
#endif /* CLI_ENABLED */
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
        	sys_capacity_set(sys_bat_capacity_get());
			sys_capacity_para_save();
#endif
            dpm_cc_state_release();
            dpm_cc_state_init();
            drv_chip_reset();
        }
    }
    else {
        vbat_val_miss_cnt = 0;
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_ERR_MASK;
    }
}

#if SYS_POWER_BANK_ENABLED
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 1
    if ((!dpm_cable_detect_done_get()))
    {
#if 0
        if ((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val >SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {
            sys_bat_current_ibat_val_inc( 90);
            
        }
        else if((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val <= SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {

             sys_bat_current_ibat_val_inc( 60);

        }
        else if((g_sys_pd_info.usba_ibus_avg_val <= SYS_USBA_IBUS_NO_CURRENT_FLOW_THR)&&
            (g_sys_pd_info.usbc2_ibus_avg_val > SYS_USBC2_IBUS_NO_CURRENT_FLOW_THR))
        {

            sys_bat_current_ibat_val_inc( 60);

        }
        else {
            sys_bat_current_ibat_val_set(SYS_USBA_IBUS_NO_CURRENT_FLOW_THR + (rand() & 0x3));
        }
#endif
    }
    else 
    {
        if (sys_bat_current_ibat_val_get() > 300)
        {
            if (sys_bat_charging_flag_get())
            {
                sys_bat_current_ibat_val_inc(90);
            }
            else {
                sys_bat_current_ibat_val_inc(180);
            }
        }
    }
#endif
#if SYS_BAT_CAP_INTEGRAL_METHOD_ENABLED
    // 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);
    }
}


#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 = SYS_LED_NUM, u8_direction = 1;

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

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

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

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

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

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

#else

#define sys_pd_display_flash_manually(cnt,fast)

#endif /* SYS_LED_ENABLED */
#if SYS_USBA_ENABLED
u32_t sys_usba1_vbus_get()
{
    return (drv_adc_read_multi_avg(SYS_USBA1_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBA_VBUS_ADC_CONSTANT)>>12;
}

u32_t sys_usba2_vbus_get()
{
    return drv_adc_read_multi_avg(SYS_USBA2_VBUS_ADC_ID, 3) * drv_flash_trim_ref_volt_get() * SYS_USBA_VBUS_ADC_CONSTANT / ADC_REF_DIVISOR;
}
bool_t sys_usba_vbus_set(u32_t volt)
{
    if ((VOLTAGE_12V < volt) || (VOLTAGE_5V > volt))
        return FALSE;

    sync_enter_critical();

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

    drv_pwm_en_set(SYS_USBA_PWM_ID, TRUE);

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

    sync_exit_critical();

    return TRUE;
}

void sys_usba_init()
{
    // read status reg
    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
#if  0 
    if (sys_gpio_usba1_insert_detect_get())
    {
        sys_gpio_usba1_power_on_set(TRUE);
        delay(500);
        sys_gpio_usba1_power_on_set(FALSE);
    }
    if (sys_gpio_usba2_insert_detect_get())
    {
        sys_gpio_usba2_power_on_set(TRUE);
        delay(500);
        sys_gpio_usba2_power_on_set(FALSE);
    }  
    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
    g_sys_pd_info.usba1_indet_current_flag = sys_gpio_usba1_insert_detect_get();
    g_sys_pd_info.usba2_indet_current_flag = sys_gpio_usba2_insert_detect_get();
    
    if (g_sys_pd_info.usba1_indet_current_flag)
    {
        g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_flag;
        g_sys_pd_info.usba1_indet_flag = g_sys_pd_info.usba1_indet_current_flag;
        sys_gpio_usba1_insert_detect_clear();
        //enble 8102
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba1_volt_check_en(TRUE);
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
        if(!g_sys_pd_info.usba2_indet_flag)
        {
             g_sys_pd_info.usba_no_current_flow_flag = FALSE;

        }
                  
#if CLI_ENABLED
        if (sys_cfg_dbg_get()) drv_uart_puts(" A1 indet init ");
#endif /* CLI_ENABLED */
       
    }
     if (g_sys_pd_info.usba2_indet_current_flag)
    {
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_flag;
        g_sys_pd_info.usba2_indet_flag = g_sys_pd_info.usba2_indet_current_flag;
        sys_gpio_usba2_insert_detect_clear();
        //enble jw5068
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);
        // Enable QC;
        if(g_sys_pd_info.usba1_indet_flag)
        {
            sys_gpio_usba2_qc_enble_set(FALSE);
             
        }
        else
        {
            sys_gpio_usba2_qc_enble_set(TRUE);
            g_sys_pd_info.usba_no_current_flow_flag = FALSE;
            g_sys_pd_info.usba2_disconnected_tick = 0;
            g_sys_pd_info.usba_no_current_start_tick = 0;
            
#if CLI_ENABLED
            if (sys_cfg_dbg_get()) drv_uart_puts(" A1 indet init and QC On");
#endif /* CLI_ENABLED */
       }
    }
#endif    
}
#endif

#if SYS_USBA_ENABLED
void sys_usba_restore()
{
    
    if (g_sys_pd_info.usba2_indet_flag &&(!g_sys_pd_info.usba1_indet_flag))
    {
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);
        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba2_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 On\n");
#endif /* CLI_ENABLED */
    }
    else if(g_sys_pd_info.usba1_indet_flag&&(!g_sys_pd_info.usba2_indet_flag))
    {
        sys_gpio_usba_dc_enble_set(TRUE);
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba1_volt_check_en(TRUE);
        
        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
#if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 Off, A1  On\n");
#endif /* CLI_ENABLED */
    }
    else if(g_sys_pd_info.usba2_indet_flag && g_sys_pd_info.usba1_indet_flag)
    {
        sys_gpio_usba_dc_enble_set(TRUE);
        
        sys_gpio_usba2_qc_enble_set(FALSE);
        
        sys_gpio_usba1_power_on_set(TRUE);
        sys_gpio_usba2_power_on_set(TRUE);
        
        sys_gpio_usba1_volt_check_en(TRUE);
        sys_gpio_usba2_volt_check_en(TRUE);
        
        g_sys_pd_info.usba_no_current_flow_flag = FALSE;
        g_sys_pd_info.usba2_disconnected_tick = 0;
        g_sys_pd_info.usba1_disconnected_tick = 0;
        g_sys_pd_info.usba_no_current_start_tick = 0;
 #if CLI_ENABLED
    	if (sys_cfg_dbg_get()) printf("Restore: A2 on, A1  On\n");
#endif /* CLI_ENABLED */

    }
}
#endif
#endif /* SYS_POWER_BANK_ENABLED */
#if 0
#define IBUS_VSAFE5V_OVER_MAX 3500

void sys_usbc_ibus_ocp()
{
    //bool_t ocp_flg= 0;
    if((!pe_pd_connected_get())&&(g_sys_pd_info.ibus_current >= IBUS_VSAFE5V_OVER_MAX)
        &&(dpm_current_pwr_mode_get()))
    {
        if(sys_bat_ibus_val_get() > IBUS_VSAFE5V_OVER_MAX)
        {
            g_sys_pd_info.usbc_src_current_ocp_flg = 1;
            printf("no pd current ocp_curr=%d\n",g_sys_pd_info.ibus_current);
        }
    }
    else if(pe_pd_connected_get()&&(dpm_current_pwr_mode_get())&&
        (g_sys_pd_info.ibus_current >= g_sys_pd_info.ibus_set_curr))
    {
        if(sys_bat_ibus_val_get() > g_sys_pd_info.ibus_set_curr)
        {

           g_sys_pd_info.usbc_src_current_ocp_flg = 1;
           printf("pd current ocp_curr=%d,curr_set=%d\n",g_sys_pd_info.ibus_current,g_sys_pd_info.ibus_set_curr);
        }

    }
    if(g_sys_pd_info.usbc_src_current_ocp_flg && dpm_vbus_source_en_get())
    {
         
         dpm_vbus_source_en_set(FALSE);
         //sys_gpio_pd_qc_led_off();
         sys_gpio_pmic_pstop_set(FALSE);
         sys_gpio_vbus_en_set(FALSE);
         sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        

    }

}
#endif
void power_key_event_detect()
{

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

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

}
void sys_qc_machine_entrence()
{

    if (usbpd_cfg_port_quick_charge_en_get())
    {
        //if (g_sys_pd_info.usba1_qc_en_flag)
        //{
        //    dpm_qc_state_machine(&g_usba1_qc_info);
        //}
        
       /* if ((!pe_pd_connected_get()) &&
            (dpm_current_pwr_mode_get()) && 
            (DPM_QC_DISABLED != dpm_qc_state_get(&g_usbc_qc_info)))
        {
            dpm_qc_state_machine(&g_usbc_qc_info);
        }*/
    }

}

void sys_init_config()
{

    // after system init 1.6 seconds, we need to enable short foldback feature
    if (10 <= g_sys_pd_info.continuous_timer_tick)
    {
        g_sys_pd_info.sys_initializing = FALSE;
       // sys_bat_dis_foldback_set(FALSE);
       // sys_bat_dis_term_set(FALSE);
#if SYS_POWER_BANK_ENABLED
        sys_bat_cap_cali();
#endif
    }

}

void sys_usbc_vbus_ocp_hanler()
{
    if (dpm_source_ocp_flag_get() && dpm_vbus_source_en_get()&&
       (g_sys_pd_info.mcu_state.discharge_en))
    {
        dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
        dpm_vbus_source_en_set(FALSE);
        //sys_gpio_pd_qc_led_off();
       // sys_gpio_pmic_pstop_set(FALSE);
        sys_gpio_vbus_en_set(FALSE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
#if CLI_ENABLED
    if (sys_cfg_dbg_get()) printf("OCP: %umV\n",dpm_vbus_volt_get());
#endif /* CLI_ENABLED */
    }

}
void sys_usbc_ocp_restore()
{

    if ((g_sys_pd_info.ocp_start_tick) &&
        (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.ocp_start_tick >= SYS_OCP_RESTORE_TIME)&&
        (g_sys_pd_info.ocp_restore_cnt < 1))
    {
        g_sys_pd_info.ocp_start_tick = 0;
        g_sys_pd_info.ocp_restore_cnt++;
        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
#if CLI_ENABLED
        if (sys_cfg_dbg_get()) puts("Auto restore");
#endif /* CLI_ENABLED */

        // restore OCP
        if (dpm_source_ocp_flag_get())
        {
            dpm_source_ocp_flag_set(FALSE);
#if CLI_ENABLED
            if (sys_cfg_dbg_get()) puts("Restore C1");
#endif /* CLI_ENABLED */
            if(g_sys_pd_info.mcu_state.discharge_en)
            {
               // sys_gpio_pmic_pstop_set(TRUE);
               // sys_gpio_vbus_en_set(TRUE);
                if (pe_pd_connected_get())
                {
                  dpm_hard_reset_req_set(TRUE);
                  pe_state_machine();  
            
                }
                else
                {
                    dpm_vbus_source_en_set(TRUE);
     #if SYS_QUICK_CHARGE_ENABLED
                    if (usbpd_cfg_port_quick_charge_en_get())
                    {
                        dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
                    }
#endif

                }

            }
            
            
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_DCHG_OCP_MASK;

        }
    }

}
void sys_deadbattery_protection()
{
   
    if ((!sys_bat_charging_flag_get()) && 
        (!pe_prs_in_prog_get()) && 
        (!dpm_port_dead_battery_get()) && 
        ((sys_bat_current_vbat_val_get() > SYS_BAT_INVALID_VOLT)))
        {
            if (usbpd_cfg_port_bat_cell_get() == SYS_BAT_4S)
            {
                if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_4S)
                {
                    sys_bat_dead_check_cnt_inc(1);
                }
                else
                {
                    sys_bat_dead_check_cnt_set(0);
                }
            }
            else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_5S)
            {
                if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_5S)
                {
                    sys_bat_dead_check_cnt_inc(1);
                }
                else{
                    sys_bat_dead_check_cnt_set(0);
                }
            }
            else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_6S)
            {
                if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_6S)
                {
                    sys_bat_dead_check_cnt_inc(1);
                }
                else
                {
                    sys_bat_dead_check_cnt_set(0);
                }
            }
            else if(usbpd_cfg_port_bat_cell_get() == SYS_BAT_7S)
            {
                if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_7S)
                {
                    sys_bat_dead_check_cnt_inc(1);
                }
                else
                {
                    sys_bat_dead_check_cnt_set(0);
                }
            }
            else if(usbpd_cfg_port_bat_cell_get() < SYS_BAT_4S)
            {
                if (sys_bat_current_vbat_val_get() <= SYS_BAT_DEAD_VOLT_UNDER_4S)
                {
                    sys_bat_dead_check_cnt_inc(1);
                }
                else
                {
                    sys_bat_dead_check_cnt_set(0);
                }
            }
            if (sys_bat_dead_check_cnt_get() >= SYS_POWER_BANK_CHECK_DEAD_BATTERY_CNT)
            {
                dpm_port_dead_battery_set(TRUE);
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_LCP_SET;
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;

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

                if (DPM_CC_ATTACHED_SRC == dpm_cc_state_get())
                {
                    dpm_vbus_source_en_set(FALSE);
                }

                // disable USB-A
                //sys_usba_vbus_set(VOLTAGE_5V);
                sys_gpio_usba1_power_on_set(FALSE);
                sys_gpio_usba2_power_on_set(FALSE);
                sys_gpio_usba_c2_enble_set(FALSE);
                //Need to flash battery cap LEDs to notice dead battery
                //sys_gpio_pd_qc_led_off();
                sys_bat_state_set(SYS_BAT_STATE_DEAD_BATTERY);
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
                sys_bat_dead_check_cnt_set(0);
            }
        }
}
void detect_current_direction()
{
    
    // get ibat value
    g_sys_bat_info.current_ibat_val = sys_bat_ibat_val_get();
    g_sys_pd_info.vbus_current = sys_bat_vbus_fb_val_get();
    g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();
#if 0
    if((g_sys_pd_info.vbus_current > 4500)&&(!usbpd_cfg_port_source_ocp_en_get())
        &&(!g_sys_pd_info.p60c_otp_flag)&&(!g_sys_pd_info.m10c_otp_flag))
    {
        usbpd_cfg_port_source_ocp_en_set(TRUE);
    }
#endif    
    // C1 power
    g_sys_pd_info.c1_current_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current;
    // A port power
    u32_t usba_pwr = 0;
#if SYS_USBA_ENABLED
    if (g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR)
    {
        usba_pwr = g_sys_pd_info.usba_ibus_avg_val + 50;
       
        usba_pwr = usba_pwr * sys_usba1_vbus_get() / SYS_BAT_DISCHARGING_EFFICIENCY;
        
    }
#endif
    if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
    {
        
        // available charge power 
        dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_CHG_SET;
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        g_sys_pd_info.c1_current_pwr *= SYS_BAT_CHARGING_EFFICIENCY;

        if (g_sys_pd_info.c1_current_pwr > usba_pwr)
        {
            sys_bat_charging_flag_set(TRUE);
            if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
            {
                sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
        		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
            }
            sys_bat_state_set(SYS_BAT_STATE_CHARGE);
            //sys_bat_current_ibat_val_set((g_sys_pd_info.c1_current_pwr - usba_pwr) / sys_bat_current_vbat_val_get());
        }
        else {
            sys_bat_charging_flag_set(FALSE);
            if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
            {
                sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
        		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
                sys_bat_charging_full_flag_set(FALSE);
                sys_bat_charging_full_tick_set(0);
            }
            sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
            //sys_bat_current_ibat_val_set((usba_pwr - g_sys_pd_info.c1_current_pwr) / sys_bat_current_vbat_val_get());
        }
    }
    else {
        dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_CHG_MASK;
        //sys_bat_charging_flag_set(FALSE);
        g_sys_pd_info.c1_current_pwr = g_sys_pd_info.c1_current_pwr / SYS_BAT_DISCHARGING_EFFICIENCY;
        //sys_bat_current_ibat_val_set((usba_pwr + g_sys_pd_info.c1_current_pwr) / sys_bat_current_vbat_val_get());
        if (sys_bat_charging_flag_get() != sys_bat_charging_pre_flag_get())
        {
    		g_sys_pd_info.bat_cap_indicator_pre_charge = 0;
    		g_sys_pd_info.bat_cap_indicator_pre_discharge = 100;
            sys_bat_charging_pre_flag_set(sys_bat_charging_flag_get());
        }
        if ((g_sys_pd_info.usba_ibus_avg_val > SYS_USBA_IBUS_HAS_CURRENT_FLOW_THR) || 
            (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE))
        {
            sys_bat_state_set(SYS_BAT_STATE_DISCHARGE);
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        }
        else if ((g_sys_pd_info.usba_ibus_avg_val <= SYS_USBA_IBUS_NO_CURRENT_FLOW_THR) && 
            (dpm_port_state_get() == DPM_PORT_STATE_IDLE))
        {
            sys_bat_state_set(SYS_BAT_STATE_IDLE);
            dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_SYS_IDLE_SET;
        }
    }
               
}

void pd_hard_reset_need_check()
{

    if ((dpm_cable_detect_done_get()) && 
        (dpm_current_pwr_mode_get()) && 
        (pe_pd_connected_time_get()) && 
        ((u32_t)(now() - pe_pd_connected_time_get()) > 3000000UL) &&
        (!dpm_hrst_due_to_no_current_flag_get()) && 
        (POWER_PROFILE_30W_FIXED <= usbpd_cfg_port_src_fixed_pwr_prof_get()) && 
        (dpm_src_obj_pos_get() > 1) && 
        (10 < g_sys_pd_info.ibus_current) && (g_sys_pd_info.ibus_current < 150))
    {
        dpm_hrst_due_to_no_current_flag_set(TRUE);
        dpm_hard_reset_req_set(TRUE);
#if CLI_ENABLED
        if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1)
        {
            printf ("Need to hrst due to no current.\n");
        }
#endif
    }
/* SYS_POWER_SOURCE_NO_CURRENT_HRST */

}

void powerkey_event_hander()
{
    g_sys_pd_info.power_down_detect_current_state = g_sys_pd_info.power_check_current_state;
    if (g_sys_pd_info.power_down_detect_current_state)
    {
        if (g_sys_pd_info.power_down_detect_current_state != g_sys_pd_info.power_down_detect_last_state)
        {
            g_sys_pd_info.power_down_detect_last_state = g_sys_pd_info.power_down_detect_current_state;
            g_sys_pd_info.power_down_detect_start_time = g_sys_pd_info.current_time;
            g_sys_pd_info.auto_power_down_last_tick = 0;
            if (dpm_port_dead_battery_get() && (!sys_bat_charging_flag_get()))
            {
                sys_bat_state_set(SYS_BAT_STATE_DEAD_BATTERY);
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
            }
            else {
                sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                if(!sys_gpio_usba_c2_enble_get())
                {

                    sys_gpio_usba_c2_enble_set(TRUE);
                    g_sys_pd_info.usba_no_current_start_tick = g_sys_pd_info.continuous_timer_tick;
                    g_sys_pd_info.usbc2_no_current_start_tick = g_sys_pd_info.continuous_timer_tick;
                }
                
            }
            if (sys_bat_charging_full_tick_get() && (g_sys_pd_info.continuous_timer_tick > SYS_BAT_CHARGE_FULL_DETETION_TIME))
            {
                sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick - SYS_BAT_CHARGE_FULL_DETETION_TIME);
            }
            if ((!dpm_port_dead_battery_get()) && (!g_sys_pd_info.p60c_otp_flag) && (!g_sys_pd_info.m10c_otp_flag))
            {
                // restore OCP
                if (g_sys_pd_info.usba_no_current_flow_flag && g_sys_pd_info.usba_ocp_flag)
                {
                    g_sys_pd_info.usba_ocp_flag = FALSE;
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Restore USB when no OCP\n");
#endif /* CLI_ENABLED */
                    //sys_usba_restore();
                }
                if (dpm_source_ocp_flag_get()||g_sys_pd_info.usbc_src_current_ocp_flg)
                {
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Restore C1 when no OCP\n");
#endif /* CLI_ENABLED */
                    dpm_source_ocp_flag_set(FALSE);
                    g_sys_pd_info.usbc_src_current_ocp_flg = FALSE;
                   // sys_gpio_pmic_pstop_set(TRUE);
                   // sys_gpio_vbus_en_set(TRUE);
                    dpm_vbus_source_en_set(TRUE);
                    if (dpm_cable_detect_done_get() && 
                        pe_pd_connected_get())
                    {
                        if (dpm_port_epr_mode_get())
                        {
                            pe_error_recovery_directed_set(TRUE);
                        }
                        else{
                            dpm_hard_reset_req_set(TRUE);
                            pe_state_machine();
                        }
                    }
                }
            }
        }
        if ((dpm_port_state_get() != DPM_PORT_STATE_CHARGE) && 
            (g_sys_pd_info.power_down_detect_last_state) && 
            (g_sys_pd_info.power_down_detect_start_time) && 
            (g_sys_pd_info.current_time > g_sys_pd_info.power_down_detect_start_time) && 
            ((g_sys_pd_info.current_time - g_sys_pd_info.power_down_detect_start_time) > SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION))
        {
            g_sys_pd_info.power_down_detect_last_state = FALSE;
#if CLI_ENABLED
			if (sys_cfg_dbg_get()) printf("Off\n");
#endif /* CLI_ENABLED */
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
            sys_capacity_set(sys_bat_capacity_get());
            sys_capacity_reset_flag_set(FALSE);
			sys_capacity_para_save();
#endif
            if (dpm_port_dead_battery_get())
            {
                dpm_port_dead_battery_set(FALSE);
                sys_bat_state_set(SYS_BAT_STATE_IDLE);
            }
#if SYS_POWER_BANK_ENABLED
            sys_pd_display_flash_manually(3,FALSE);
#endif
            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)
                {
#if SYS_POWER_BANK_ENABLED
                    sys_pd_display_flash_manually(3,TRUE);
#endif
                }
            }
            if ((now() - g_sys_pd_info.power_down_detect_start_time) > SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
            {
                sys_cfg_erase();
                sys_capacity_para_erase();
            }
             //disable 8812 pstop
           // sys_gpio_pmic_pstop_set(FALSE);
            // 8812 ad_start set 1
            SYS_BAT_REG_FIELD_SET(CTRL3_SET_REG,AD_START,FALSE);
            sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
            SYS_BAT_REG_SET(MASK_REG,0x8e);
            printf("MASK_REG=0x%x\n",SYS_BAT_REG_GET(MASK_REG));
            //usba indet1 indet2 mask set 1
            // disable USB-A
            //sys_gpio_usba_dc_enble_set(FALSE);
           // sys_gpio_usba2_qc_enble_set(FALSE);
            //sys_gpio_usba1_power_on_set(FALSE);
           // sys_gpio_usba2_power_on_set(FALSE);
            //sys_gpio_usba1_volt_check_en(TRUE);
           // sys_gpio_usba2_volt_check_en(TRUE);
            sys_gpio_usba_c2_enble_set(FALSE);
            sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
            printf("STATUS_REG=0x%x\n",SYS_BAT_REG_GET(STATUS_REG));
            dpm_cc_state_release();
            dpm_cc_state_init();
            dpm_rp_rd_clear();
            //sys_cmd_port_disable_set(TRUE);
            rtc_delay_us(1000000UL);
            DRV_INTR_GLOBAL_DISABLE();
            sys_gpio_power_on_set(OFF);
            sys_tick_t power_off = now();
            while(1)
	        {
				//printf("power off2!\n");
				
				if((now()-power_off)>SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
				{
					break;
				}
			}
            drv_chip_reset();
        }
    }
    else {
        g_sys_pd_info.power_down_detect_last_state = 0;
        g_sys_pd_info.power_down_detect_start_time = 0;
    }

}
#if SYS_USBA_ENABLED
void usba_current_check()
{
    g_sys_pd_info.usba_ibus_accum_val += sys_usba_ibus_get();
    g_sys_pd_info.usba_ibus_accum_val_idx++;
    if (g_sys_pd_info.usba_ibus_accum_val_idx >= SYS_USBA_IBUS_ACCUM_VAL_IDX_MAX)
    {
        g_sys_pd_info.usba_ibus_avg_val = g_sys_pd_info.usba_ibus_accum_val / g_sys_pd_info.usba_ibus_accum_val_idx;
    	g_sys_pd_info.usba_ibus_accum_val = 0;
        g_sys_pd_info.usba_ibus_accum_val_idx = 0;

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

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

                if ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.auto_power_down_last_tick) >= SYS_POWER_BANK_AUTO_POWER_DOWN_DELAY)
                {
                    g_sys_pd_info.usba_no_current_flow_last_flag = FALSE;
#if CLI_ENABLED
    				if (sys_cfg_dbg_get()) printf("Auto off\n");
#endif /* CLI_ENABLED */
                    // flash 3 times
#if SYS_CAPACITY_PARA_SAVE_TO_FLASH
    				sys_capacity_set(sys_bat_capacity_get());
                    sys_capacity_reset_flag_set(FALSE);
    		        sys_capacity_para_save();
#endif
                    if (dpm_port_dead_battery_get())
                    {
                        dpm_port_dead_battery_set(FALSE);
                        sys_bat_state_set(SYS_BAT_STATE_IDLE);
                    }
#if SYS_POWER_BANK_ENABLED                    
                    sys_pd_display_flash_manually(3,FALSE);
#endif
                    //sys_pd_led_state_set(SYS_PD_LED_STATE_OFF);
                    //sys_cmd_port_disable_set(TRUE);
                    // disable USB-A
                        //disable 8812 pstop
#if 0                        
                    sys_gpio_pmic_pstop_set(FALSE);
                    // 8812 ad_start set 1
                    SYS_BAT_REG_FIELD_SET(CTRL3_SET_REG,AD_START,FALSE);
                    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
                    SYS_BAT_REG_SET(MASK_REG,0x8e);
                  
                    sys_gpio_usba_c2_enble_set(FALSE);
                    sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
#endif                    
                    dpm_cc_state_release();
                    dpm_cc_state_init();
                    dpm_rp_rd_clear();
                    rtc_delay_us(1000000UL);
                    DRV_INTR_GLOBAL_DISABLE();
                    sys_gpio_power_on_set(OFF);
                    sys_tick_t power_off = now();
                    while(1)
                    {
    					//printf("power off2!\n");
    					
    					if((now()-power_off)>SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL)
    					{
    						break;
    					}
    				}
                    drv_chip_reset();
                }
            }
        }
        else {
            g_sys_pd_info.auto_power_down_last_tick = 0;
            //dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_SYS_IDLE_MASK;
        }
    }


}
#if SYS_OVERTEMP_DECTION_ENABLED 

void sys_ntc_temp_protection()
{

    if (!g_sys_pd_info.ntc_test_flag)
    {
        //g_sys_pd_info.ntc_volt = drv_adc_read_multi_avg(SYS_NTC_ADC_ID,5) * drv_flash_trim_ref_volt_get() * 10 / ADC_REF_DIVISOR;
        g_sys_pd_info.ntc_volt = sys_bat_adin_val_get() * 10;
    }
    g_sys_pd_info.p60c_otp_pre_flag = g_sys_pd_info.p60c_otp_flag;
    g_sys_pd_info.p55c_otp_pre_flag = g_sys_pd_info.p55c_otp_flag;
    g_sys_pd_info.p45c_otp_pre_flag = g_sys_pd_info.p45c_otp_flag;
    g_sys_pd_info.p40c_otp_pre_flag = g_sys_pd_info.p40c_otp_flag;
    g_sys_pd_info.p0c_otp_pre_flag = g_sys_pd_info.p0c_otp_flag;
    g_sys_pd_info.m10c_otp_pre_flag = g_sys_pd_info.m10c_otp_flag;
    if (g_sys_pd_info.ntc_volt < DPM_TEMP_INVALID_VOLT)
    {
        /** Temperature greater than 60C, disable charge and discharge */
        if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P60C_VOLT)
        {
            if (!g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = TRUE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTP 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(sys_sc8815_current_min);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
            }

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

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

            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
                sys_bat_ibus_set(sys_sc8815_current_min);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;
                dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_OTP_SET;
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_P40C_VOLT) /** Temperature greater than 40C, halve charge power */
        {
            if (g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (g_sys_pd_info.m10c_otp_flag)
            {
                g_sys_pd_info.m10c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR -10C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (!g_sys_pd_info.p40c_otp_flag)
            {
                g_sys_pd_info.p40c_otp_flag = TRUE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTP 45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (dpm_port_state_get() == DPM_PORT_STATE_CHARGE)
            {
                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                    sys_bat_rated_charging_current_set((sys_bat_rated_charging_current_get() >> 1));
                    sys_bat_ibus_set(sys_bat_rated_charging_current_get());
                }
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_0C_VOLT)
        {
            if (g_sys_pd_info.p60c_otp_flag)
            {
                g_sys_pd_info.p60c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR 60C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (g_sys_pd_info.m10c_otp_flag)
            {
                g_sys_pd_info.m10c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("DCHG:OTR -10C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (g_sys_pd_info.p40c_otp_flag)
            {
                g_sys_pd_info.p40c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (g_sys_pd_info.p45c_otp_flag)
            {
                g_sys_pd_info.p45c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if (g_sys_pd_info.p0c_otp_flag)
            {
                g_sys_pd_info.p0c_otp_flag = FALSE;
#if CLI_ENABLED
				if (sys_cfg_dbg_get()) printf("CHG:OTR 0-45C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }
            if ((dpm_port_state_get() == DPM_PORT_STATE_CHARGE) && 
                (g_sys_pd_info.charging_current_saved))
            {
                sys_bat_rated_charging_current_set(g_sys_pd_info.charging_current_saved);
                //sys_bat_ibus_set(g_sys_pd_info.charging_current_saved);
                sys_bat_ibus_set(500);
                g_sys_pd_info.charging_current_saved = 0;
                sys_bat_charging_current_reach_peak_flag_set(FALSE);
                dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
                dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_OTP_MASK;
            }
        }
        else if (g_sys_pd_info.ntc_volt <= DPM_TEMP_M5C_VOLT)
        {
            if (!g_sys_pd_info.p0c_otp_flag)
            {
                g_sys_pd_info.p0c_otp_flag = TRUE;
#if CLI_ENABLED
			    if (sys_cfg_dbg_get()) printf("CHG:OTP -5-0C(%u)\n",g_sys_pd_info.ntc_volt);
#endif /* CLI_ENABLED */
            }

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

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

        // retore 
        if ((((g_sys_pd_info.p60c_otp_pre_flag)&& (!g_sys_pd_info.p60c_otp_flag)) || 
            ((g_sys_pd_info.m10c_otp_pre_flag)&& (!g_sys_pd_info.m10c_otp_flag))) && 
            (!dpm_port_dead_battery_get()))
        {
            //sys_usba_restore();
            sys_gpio_pmic_pstop_set(TRUE);
            sys_gpio_vbus_en_set(TRUE);
            usbpd_cfg_port_source_ocp_en_set(TRUE);
            dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_DISCHG_SET;
            dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_OTP_MASK;
            if ((dpm_cable_detect_done_get()) && 
                (dpm_current_pwr_mode_get()))
            {
                if (pe_pd_connected_get())
                {
                    if(!dpm_port_epr_mode_get())
                    {
                        dpm_hard_reset_req_set(TRUE);
                        pe_state_machine();
                    }
                    else
                    {
                        pe_error_recovery_directed_set(TRUE);
                    }
                }
                else {
                    dpm_vbus_source_en_set(TRUE);
#if SYS_QUICK_CHARGE_ENABLED
                    if (usbpd_cfg_port_quick_charge_en_get())
                    {
                        dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
                    }
#endif
                }
            }
        }
    }
    
}
#endif

void usbc_volt_adjust()
{
    if (dpm_cable_detect_done_get())
    {
        if (POWER_MODE_SINK == dpm_current_pwr_mode_get() && 
            (!pe_prs_in_prog_get()))
        {
            // need to draw current flow smoothly
            sys_bat_charge_current_update();
        }
#if SYS_VOLTAGE_COMPENSATION_ENABLED
        else if (dpm_current_pwr_mode_get() && 
            (!dpm_port_dead_battery_get()) && 
            pe_pd_connected_get() && 
            (!pe_prs_in_prog_get()) && 
            (dpm_src_obj_pos_get() > 0) && 
            (POWER_SUPPLY_TYPE_FIXED == usbpd_cfg_port_src_pwr_supply_type_get((dpm_src_obj_pos_get()-1))))
        {
            u32_t vbus_cfg = usbpd_cfg_port_src_fixed_pwr_volt_cap_get((dpm_src_obj_pos_get()-1))*VOLTAGE_DIV + SYS_POWER_BANK_VOLTAGE_COMPENSATION;
            u32_t ibus_cfg = usbpd_cfg_port_src_fixed_pwr_curr_cap_get((dpm_src_obj_pos_get()-1))*CURRENT_DIV ;
            
            if (ibus_cfg >= CURRENT_3000mA) 
            {
                ibus_cfg = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO * ibus_cfg + SYS_POWER_BANK_CURRENT_COMPENSATION;
                
            }
            else {
                ibus_cfg = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * ibus_cfg + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
            }
            if ((g_sys_pd_info.ibus_current >= 4000)&&(!g_sys_pd_info.usbc_curr_4a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+500U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED							
                if (sys_cfg_dbg_get()) printf("usbc_curr_4a_vol_chang_flag\n");
#endif							
                
            }
            else if ((g_sys_pd_info.ibus_current >= 3200)&&(g_sys_pd_info.ibus_current < 4000)&&(!g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+300U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED								
               if (sys_cfg_dbg_get()) printf("usbc_curr_3.2a_vol_chang_flag\n");
#endif						   
            }
            else if ((g_sys_pd_info.ibus_current >= 2400)&&(g_sys_pd_info.ibus_current < 3200)&&(!g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+250U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED							
               if (sys_cfg_dbg_get()) printf("usbc_curr2.4a_vol_chang_flag\n");
#endif						   
            }
            else if ((g_sys_pd_info.ibus_current >= 1600)&&(g_sys_pd_info.ibus_current < 2400)&&(!g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+150U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED							
                if (sys_cfg_dbg_get()) printf("usbc_curr1.6a_vol_chang_flag\n");
#endif							
               
            }
            else if ((g_sys_pd_info.ibus_current >= 800)&&(g_sys_pd_info.ibus_current < 1600) &&(!g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag))
            {
                sys_bat_discharge_vbus_ibus_set(vbus_cfg+100U,ibus_cfg, OUT_DIR);
                g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = TRUE;
                g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = FALSE;
#if CLI_ENABLED							
                if (sys_cfg_dbg_get())  printf("usbc_curr0.8a_vol_chang_flag\n");
				
#endif                           
            }
            else 
            {
                if((g_sys_pd_info.ibus_current < 800)&&(!g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag))
                {
                    sys_bat_discharge_vbus_ibus_set(vbus_cfg,ibus_cfg, OUT_DIR);
                    g_sys_pd_info.usbc_curr_4a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_3p2a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_2p4a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_1p6a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_0p8a_vol_chang_flag = FALSE;
                    g_sys_pd_info.usbc_curr_u0p6a_vol_chang_flag = TRUE;
#if CLI_ENABLED								
                    if (sys_cfg_dbg_get()) printf("usbc_curr<0.8a_vol_chang_flag\n");
					
#endif		

                }
			}
        }
#endif /* SYS_VOLTAGE_COMPENSATION_ENABLED */
    }
   
}
void dead_battery_exit_checkout()
{
    if (dpm_port_dead_battery_get())
    {
        if (!pe_prs_in_prog_get())
        {
            /* Enable charging in non-PD mode, and clear dead battery flag */
            if ((((PE_SNK_READY == pe_state_get()) && 
                (1 <= dpm_rx_src_cap_num_get()) && 
                (dpm_rx_src_cap_max_power_get() >= DEFAULT_MIN_PD_POWER)) || 
                ((DPM_CC_ATTACHED_SNK == dpm_cc_state_get()) && 
                ((g_pe_info.hard_reset_cnt > N_HARD_RESET_CNT)))))
            {
                if ((PE_SNK_READY == pe_state_get()) && (1 == dpm_rx_src_cap_num_get()) && 
                    (((UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(CFG_VOLTAGE_5V_IDX))->dual_role_pwr) && 
                    (((UPD_DATA_MSG_SOURCE_CAP_FIXED_SUPPLY_t *)dpm_rx_src_cap_object_get(CFG_VOLTAGE_5V_IDX))->usb_comm_cap))
                {
#if CLI_ENABLED
            		if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2) printf("NC\n");
#endif /* CLI_ENABLED */
                }
                else {
#if CLI_ENABLED
    		        if (sys_cfg_dbg_get()) printf("Dead exit:%umV\n", sys_bat_current_vbat_val_get());
#endif /* CLI_ENABLED */
                    dpm_port_dead_battery_set(FALSE);
                    dpm_ctrl_state &= DPM_EX_MCU_CTRL_REG_LCP_MASK;
                    //sys_usba_restore();
                    if (sys_pd_led_state_get() == SYS_PD_LED_STATE_FLASH_FAST)
                    {
                        sys_bat_state_set(SYS_BAT_STATE_CHARGE);
                        sys_pd_led_state_set(SYS_PD_LED_STATE_ON);
                    }
                }
            }
        }
    }

}

void battery_charging_isfull()
{
#if SYS_SMG_DISPLAY_ENABLED  /* modified by James Gan - 2019-11-25 */
    if ((dpm_cable_detect_done_get()) && 
        (sys_bat_charging_flag_get()) && 
        (!dpm_current_pwr_mode_get()) && 
        (sys_bat_capacity_get() >= 100) && 
        (sys_bat_avg_ibat_val_get() < 300) && 
        (sys_bat_charging_start_tick_get() > 0) &&
        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_start_tick_get()) && 
        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_start_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME) && 
        (!sys_bat_charging_full_tick_get()))
    {
        sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick);
    }
#else
    if ((dpm_cable_detect_done_get()) && 
        (sys_bat_charging_flag_get()) && 
        (!dpm_current_pwr_mode_get()) && 
        (sys_bat_capacity_get() >= 90) && 
        (sys_bat_avg_ibat_val_get() < 400) && 
        (sys_bat_charging_start_tick_get() > 0) &&
        (g_sys_pd_info.continuous_timer_tick > sys_bat_charging_start_tick_get()) && 
        ((g_sys_pd_info.continuous_timer_tick - sys_bat_charging_start_tick_get()) > SYS_BAT_CHARGE_FULL_DETETION_TIME) && 
        (!sys_bat_charging_full_tick_get()))
    {
        sys_bat_charging_full_tick_set(g_sys_pd_info.continuous_timer_tick);
    }
#endif /* #if SYS_SMG_DISPLAY_ENABLED */

}

void sys_small_current_mode()
{
    if (g_sys_pd_info.prevent_auto_poweroff)
    {
        if (g_sys_pd_info.prevent_auto_poweroff_last_state != g_sys_pd_info.prevent_auto_poweroff)
        {
            g_sys_pd_info.prevent_auto_poweroff_last_state = g_sys_pd_info.prevent_auto_poweroff;
            
           // sys_gpio_usba_dc_enble_set(TRUE);
            
            //sys_gpio_usba1_volt_check_en(TRUE);
           // sys_gpio_usba2_volt_check_en(TRUE);
           //sys_gpio_usba_c2_enble_set(TRUE);

#if CLI_ENABLED
            if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_1) printf("DCHG LI\n");
#endif /* CLI_ENABLED */
            if (!g_sys_pd_info.usba_ocp_flag)
            {

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

}
#if SYS_USBA_ENABLED
void sys_usba_indet_detect()
{ 
    if ((!g_sys_pd_info.usba_ocp_flag) && (!(g_sys_pd_info.prevent_auto_poweroff)))
    {
       
#if 1                       
       g_sys_pd_info.usba1_indet_pre_flag = g_sys_pd_info.usba1_indet_current_flag;
       g_sys_pd_info.usba1_indet_current_flag = sys_gpio_usba1_insert_detect_get();
       
       if (g_sys_pd_info.usba1_indet_current_flag)
       {
           if ((g_sys_pd_info.usba1_indet_current_flag != g_sys_pd_info.usba1_indet_pre_flag) &&
               (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba1_disconnected_tick > 4))
           {
               g_sys_pd_info.usba1_indet_flag = g_sys_pd_info.usba1_indet_current_flag;
               sys_gpio_usba1_insert_detect_clear();      
               
               g_sys_pd_info.usba_no_current_flow_flag = FALSE;
               g_sys_pd_info.usba1_disconnected_tick = 0;
               g_sys_pd_info.usba_no_current_start_tick = 0;
               sys_gpio_usba_dc_enble_set(TRUE);
               sys_gpio_usba2_qc_enble_set(FALSE);
               sys_gpio_usba1_power_on_set(TRUE);
               sys_gpio_usba1_volt_check_en(TRUE);
                                      
#if CLI_ENABLED
               if (sys_cfg_dbg_get()) drv_uart_puts("A1 indet");
#endif /* CLI_ENABLED */
           }
       }
#endif
#if 1                                           
        g_sys_pd_info.usba2_indet_pre_flag = g_sys_pd_info.usba2_indet_current_flag;
        g_sys_pd_info.usba2_indet_current_flag = sys_gpio_usba2_insert_detect_get();
        
        if (g_sys_pd_info.usba2_indet_current_flag)
        {
            if ((g_sys_pd_info.usba2_indet_current_flag != g_sys_pd_info.usba2_indet_pre_flag) &&
                (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba2_disconnected_tick > 4))
            {
                g_sys_pd_info.usba2_indet_flag = g_sys_pd_info.usba2_indet_current_flag;
                sys_gpio_usba2_insert_detect_clear();      
                sys_gpio_usba_dc_enble_set(TRUE);
                
                sys_gpio_usba2_power_on_set(TRUE);
                sys_gpio_usba2_volt_check_en(TRUE);
                
                g_sys_pd_info.usba_no_current_flow_flag = FALSE;
                g_sys_pd_info.usba2_disconnected_tick = 0;
                g_sys_pd_info.usba_no_current_start_tick = 0;
               
                if(g_sys_pd_info.usba1_indet_flag)
                {
                    sys_gpio_usba2_qc_enble_set(FALSE);
                    
                }
                else
                {
                    sys_gpio_usba2_qc_enble_set(TRUE);

                }                            
#if CLI_ENABLED
                if (sys_cfg_dbg_get()) drv_uart_puts("A2 indet");
#endif /* CLI_ENABLED */
            }
        }
#endif

    }
}
void sys_usba_unload()
{
    if ((!g_sys_pd_info.usba_ocp_flag) && (!(g_sys_pd_info.prevent_auto_poweroff)))
    {
#if 0
        if ((g_sys_pd_info.usba2_indet_flag||g_sys_pd_info.usba1_indet_flag) && 
            (g_sys_pd_info.usba_no_current_flow_flag) && 
            (g_sys_pd_info.usba_no_current_start_tick) && 
            (g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.usba_no_current_start_tick > SYS_USBA_CONNECTION_TIMEOUT))
        {
            g_sys_pd_info.usba2_indet_flag = FALSE;
            g_sys_pd_info.usba1_indet_flag = FALSE;
            
            sys_gpio_usba_dc_enble_set(FALSE);
            sys_gpio_usba2_qc_enble_set(FALSE);
            sys_gpio_usba1_power_on_set(FALSE);
            sys_gpio_usba2_power_on_set(FALSE);
            sys_gpio_usba1_volt_check_en(FALSE);
            sys_gpio_usba2_volt_check_en(FALSE);
            g_sys_pd_info.usba2_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
            g_sys_pd_info.usba1_disconnected_tick = g_sys_pd_info.continuous_timer_tick;

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

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


void sys_usba_ocp_protection()
{

#if 0
    if (((sys_gpio_usba1_power_on_get()) && 
        (((g_sys_pd_info.usba_vbus_val <= VSAFE_5V_DISCONNECT)&&
        (sys_usba_ibus_get()>1000))|| 
        (g_sys_pd_info.usba_vbus_val * sys_usba_ibus_get() >= 22000000UL)))
        ||(sys_gpio_usba2_power_on_get()&&(((g_sys_pd_info.usba2_vbus_val <= VSAFE_5V_DISCONNECT)&&
        (sys_usba_ibus_get()>1000))
        ||(g_sys_pd_info.usba2_vbus_val * sys_usba_ibus_get() >= 22000000UL))))
        
    {
        g_sys_pd_info.usba_ocp_flag = TRUE;
        sys_gpio_usba2_qc_enble_set(FALSE);
        sys_gpio_usba1_power_on_set(FALSE);
        sys_gpio_usba2_power_on_set(FALSE);
        sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
        g_sys_pd_info.usba1_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
        g_sys_pd_info.usba2_disconnected_tick = g_sys_pd_info.continuous_timer_tick;
#if CLI_ENABLED
		if (sys_cfg_dbg_get()) printf("USB-A OCP, Power Off\n");
#endif /* CLI_ENABLED */
    } 
#endif    
   
   

}

#endif
void sys_usbc_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);
    }
    
}
void sys_shutdown(void)
{
    if (dpm_port_dead_battery_get())
    {
        dpm_port_dead_battery_set(FALSE);
        sys_bat_state_set(SYS_BAT_STATE_IDLE);
    }
    
    dpm_cc_state_release();
    dpm_cc_state_init();
    dpm_rp_rd_clear();
    rtc_delay_us(1000000UL);
    DRV_INTR_GLOBAL_DISABLE();
    sys_gpio_power_on_set(OFF);
    
    sys_tick_t start = now();
    while (((u32_t)(now() - start) < SYS_POWER_BANK_POWER_DOWN_DETECT_DURATION_UL));
}

void sys_qc_led_ctr()
{
    if((!sys_gpio_pd_qc_led_get())&&(((g_sys_pd_info.vbus_current > 5500 )&&(dpm_cable_detect_done_get()))
        ||(( g_sys_pd_info.usba_vbus_val > 5500)&&(sys_gpio_usba_c2_enble_get()))
        ||((g_sys_pd_info.usbc2_vbus_val> 5500)&&(sys_gpio_usba_c2_enble_get()))))
    {
        sys_gpio_pd_qc_led_on();


    }
    if((sys_gpio_pd_qc_led_get())&&((g_sys_pd_info.vbus_current <5200)&&(g_sys_pd_info.usba_vbus_val <5200)
        &&(g_sys_pd_info.usbc2_vbus_val <5200)))
        {

        sys_gpio_pd_qc_led_off();

    }
}
void sys_mcu_charge_discharge_ctrl()
{
        *(u8_t *)(&g_sys_pd_info.mcu_state_pre) = *(u8_t *)(&g_sys_pd_info.mcu_state);
        *(u8_t *)(&g_sys_pd_info.mcu_state)= dpm_ex_pw_ctrl_get();
        if((dpm_port_state_get()== DPM_PORT_STATE_CHARGE)&&
          (g_sys_pd_info.mcu_state.charge_en != g_sys_pd_info.mcu_state_pre.charge_en))
        {
 #if USBPD_DEBUG_ENABLED
    		if (usbpd_cfg_dbg_get()) 
    		{

                printf("charge mcu_ctrl_state=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state));
                printf("charge mcu_ctrl_state_pre=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state_pre));

            }
#endif /* CLI_ENABLED */
            if(g_sys_pd_info.mcu_state.charge_en)
            {
                if(g_sys_pd_info.charging_current_saved)
                {
                    sys_bat_rated_charging_current_set(g_sys_pd_info.charging_current_saved);
                    sys_bat_ibus_set(g_sys_pd_info.charging_current_saved);
                    g_sys_pd_info.charging_current_saved = 0;
                    sys_bat_charging_current_reach_peak_flag_set(FALSE);

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

                }
                if(!sys_gpio_vbus_en_get())
                {
                   // sys_gpio_vbus_en_set(TRUE);

                }
                dpm_ctrl_mcu_set_state |= DPM_EX_MCU_SET_STA_REG_CHG_SET;
            }
            else
            {

                if (!g_sys_pd_info.charging_current_saved)
                {
                    g_sys_pd_info.charging_current_saved = sys_bat_rated_charging_current_get();
                }
                sys_bat_rated_charging_current_set(0);
             //   sys_bat_ibus_set(sys_sc8815_current_min);
              //  sys_gpio_pmic_pstop_set(FALSE);
                sys_bat_charging_current_reach_peak_flag_set(TRUE);
                dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_CHG_MASK;

            }

        }
        if((dpm_port_state_get()==DPM_PORT_STATE_DISCHARGE)&&
          (g_sys_pd_info.mcu_state.discharge_en != g_sys_pd_info.mcu_state_pre.discharge_en))
        {
#if USBPD_DEBUG_ENABLED
    		if (usbpd_cfg_dbg_get()) 
    		{
                printf("discharge mcu_ctrl_state=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state));
                printf("discharge mcu_ctrl_state_pre=0x%x\n",*(u8_t *)(&g_sys_pd_info.mcu_state_pre));

            }
#endif /* CLI_ENABLED */
            if((g_sys_pd_info.mcu_state.discharge_en)&&
                (!dpm_port_dead_battery_get())&&
                (!dpm_source_ocp_flag_get()))
            {
#if 0                    
                sys_gpio_pmic_pstop_set(TRUE);
                sys_gpio_vbus_en_set(TRUE);
                //usbpd_cfg_port_source_ocp_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);
#if SYS_QUICK_CHARGE_ENABLED
                        if (usbpd_cfg_port_quick_charge_en_get())
                        {
                            dpm_qc_enable_set(&g_usbc_qc_info, TRUE, FALSE);
                        }
#endif
                    }
                }
                
#else
                pe_error_recovery_directed_set(TRUE);

#endif
            }
            else
            {
                if(dpm_vbus_source_en_get())
                {
                    dpm_vbus_source_en_set(FALSE);
                  //  sys_gpio_pmic_pstop_set(FALSE);
                    sys_gpio_vbus_en_set(FALSE);
                    //usbpd_cfg_port_source_ocp_en_set(FALSE);
                    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
                }
#if SYS_QUICK_CHARGE_ENABLED
                if (usbpd_cfg_port_quick_charge_en_get())
                {
                    dpm_qc_enable_set(&g_usbc_qc_info, FALSE, FALSE);
                }
#endif
            }

        }
        if ((!dpm_cable_detect_done_get())&&
            (g_sys_pd_info.mcu_state.power_off))
        {
            sys_shutdown();
        }
}

#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;
        }
        else {
            current = SYS_POWER_BANK_DICCHARGE_CURRENT_COMPENSATION_RATIO2 * current + SYS_POWER_BANK_CURRENT_COMPENSATION_2;
        }

        if ((POWER_SUPPLY_TYPE_FIXED == usbpd_cfg_port_src_pwr_supply_type_get((dpm_src_obj_pos_get()-1))) &&
            (g_sys_pd_info.ibus_current >= current))
        {
             g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();
                        
            if(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
            {
                return FALSE;

            }
        }
        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))
        {
            g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();
            if(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;
        }
    }
    else {
        return FALSE;
    }
}

void sys_pd_check_epr()
{
	// sink request process
	if (PE_SNK_READY == pe_state_get())
	{

			int cap_pos = dpm_src_obj_pos_get();
			u32_t volt;
			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;

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

			}
			else {
				volt = p_src_cap_fixed->volt * VOLTAGE_DIV;

			}

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


void sys_pd_auto_prs()
{
    if ((1) &&   //sys_gpio_c1_connected_get
        (dpm_cable_detect_done_get()) &&
        (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get()))
    {
        if ((pe_state_is_snk_rdy()) &&
            (!dpm_pr_swp_requested_flag_get()))
        {

            if ( 1   //1 == dpm_rx_src_cap_num_get()
                )
            {
                if (drv_timer_stopped(&(g_dpm_info.pr_swp_request_timer)) &&
                    !drv_timer_expired(&(g_dpm_info.pr_swp_request_timer)))
                {
                    drv_timer_start(T_PR_SWP_REQUEST_TIMER,
                        &(g_dpm_info.pr_swp_request_timer), NULL);
                }

                if (drv_timer_expired(&(g_dpm_info.pr_swp_request_timer)))
                {
                    dpm_pr_swp_req_set(TRUE);
                    dpm_pr_swp_requested_flag_set(TRUE);
                }
            }
        }

#if 0
        if ((VBUS_CURR_HANDLING_CAP_RESV == dpm_rx_vdm_ack_cable_vbus_curr_cap_get()) &&
            (usbpd_cfg_port_vconn_en_get()) &&
            (pe_state_is_src_rdy()) &&
            (dpm_pr_swp_requested_flag_get()) &&
            (!dpm_vdm_disc_ident_requested_flag_get()))
        {
            if ((!dpm_vcon_swp_requested_flag_get()))
            {
                dpm_vconn_swp_req_set(TRUE);
                dpm_vcon_swp_requested_flag_set(TRUE);
            }

            if ((dpm_vcon_swp_requested_flag_get()) &&
                (dpm_presently_vconn_source_get()))
            {
                if ((dpm_ufp_mode_get()) &&
                    (DPM_SOP_CAB_TYPE_RX_ALL != dpm_sop_cbl_type_get()))
                {
                    dpm_sop_cbl_type_set(DPM_SOP_CAB_TYPE_RX_ALL);
                }
                else if ((DPM_SOP_CAB_TYPE_RX_ALL == dpm_sop_cbl_type_get()))
                {
                    pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOPP);
                    dpm_vdm_disc_ident_requested_flag_set(TRUE);
                }
            }
        }
#endif
        if (pe_state_is_snk_rdy())
        {
            if ((dpm_prs_req_rejected_get()) &&
                (dpm_pr_swp_requested_flag_get()) &&
                (!pe_error_recovery_directed_get()))
            {
                pe_error_recovery_directed_set(TRUE);
                dpm_prs_req_rejected_set(FALSE);
                if (sys_cfg_dbg_get()) puts("PRS REJECT, ERR");
            }
        }
    }

}


//static u8_t hdp_out_atantion = 0;


#define USBA_DP_DLY 30000

 //static u8_t a_to_cflag = 0;
//static u32_t cnt11 = 0;

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

    sys_tick_t start_time = now();


    static u8_t a_to_cflag = 0;



    if (g_sys_pd_info.hpd_detect_start_time && (!alt_holdout_get())&&
           (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

            //printf("hdp lost2s \r\n");
            //attention_hdp_flg
            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 < 5) &&
		   (!pe_prs_in_prog_get()))
       {
            //printf("hdp irq \r\n");
            rtc_delay_us(1000);  //
            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++;
            a_to_cflag = 1;
       }
       else
       {
           g_sys_pd_info.attention_req_flg = FALSE;
       }




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

#if SYS_POWER_KEY_ENABLED    
    power_key_event_detect();
#endif
#if 0
    if (sys_mcu_int_get())
    {
        drv_gpio_intr_en_set(sys_gpio_mcu_i2c_int, FALSE);
        
        sys_mcu_int_en_set(FALSE);
        drv_gpio_intr_en_set(sys_gpio_mcu_i2c_int, TRUE);
    }
#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 + 5)) &&
        ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.attention_start_tick) > 10)&&
        (alt_holdout_get()))
		    // (pe_state_get() == PE_SRC_READY) &&
            //(dpm_ufp_mode_get()))
       {
            //printf("hdp  attenion 1\r\n");
            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_start_tick = 0;
            prl_msg_tx(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
            drv_gpio_intr_polar_set(DSVL_HPDOUT, 0);
            drv_gpio_intr_en_set(DSVL_HPDOUT, TRUE);
       }

    if (g_sys_pd_info.switch_games_mode && 
        (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) > 3)&&
        (alt_holdout_get()))
    {
        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_start_tick = 0;
        prl_msg_tx(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
        drv_gpio_intr_polar_set(DSVL_HPDOUT, 0);
        drv_gpio_intr_en_set(DSVL_HPDOUT, TRUE);
    }

    //handler QC state machine
#if SYS_QUICK_CHARGE_ENABLED

    sys_qc_machine_entrence();

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



          /* sys_pd_auto_prs();

			if (!sys_gpio_c1_connected_get())
			{
				if (dpm_port_state_get() == DPM_PORT_STATE_DISCHARGE)
				{
					if (!pe_error_recovery_directed_get())
					{
						pe_error_recovery_directed_set(TRUE);
						if (sys_cfg_dbg_get()) puts("SRC to SNK, ERR");
					}
				}
				if ((usbpd_cfg_port_def_pr_get() == POWER_ROLE_DRP) &&
					(!pe_error_recovery_directed_get()) &&
					(!dpm_cable_detect_done_get()) &&
					(!pe_prs_in_prog_get()))
				{
					usbpd_cfg_port_def_pr_set(POWER_ROLE_SINK);
					usbpd_cfg_port_def_pdr_set(PD_ROLE_CONSUMER);
					usbpd_cfg_port_dual_role_pwr_set(TRUE);
					dpm_port_reset();
					if (sys_cfg_dbg_get()) puts("DRP to SNK");
				}
			}
*/



#if 1
        static u32_t led_cnt = 0;
        if (dpm_cable_detect_done_get()&& !sys_cfg_dbg_get())
        {
              if((a_to_cflag == 1)||(led_cnt > 40))
              {
            	     a_to_cflag = 0;
#if OPEN_DPDMSWAP
                     sys_alt_usbc_to_a(TRUE);  //打开模拟开关 开机3秒打开模拟开关，打开了模拟开关会关闭串口

#endif
              }
        }

            led_cnt ++;
       		if(led_cnt > 100)
       		{


       			led_cnt = 0;
       		}
#endif
#if 0
			if(PE_SNK_READY == pe_state_get())
			{
				one_up_src = 0;

			}

			if(alt_sink_int_flag && one_uptime)  /*io 中断读取I2C，不能在中断函数读，不然读取不到？*/
			{


				  u32_t set_pos_state = POWER_PROFILE_100W_FIXED;
				  u8_t alt_tmp_cur[8];

				  if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
				  {
					  printf("sink borad input\r\n");
				   }
				  if(one_up_src == 0)
				 {
					  one_up_src = 1;
					  alt_sink_curcap_get(alt_tmp_cur,6);  /*对着协议*/

					  if(alt_tmp_cur[0] ==  I2C_ACK_DAT)
					  {

						  g_sys_pd_info.alt_sink12v_cur = alt_tmp_cur[1];
						  g_sys_pd_info.alt_sink15v_cur = alt_tmp_cur[2];
						  g_sys_pd_info.alt_sink20v_cur = alt_tmp_cur[3];
						  g_sys_pd_info.alt_sink_maxpos = alt_tmp_cur[5];

					  }
					  else g_sys_pd_info.alt_sink20v_cur = 30;  //出错默认3A


					   sys_alt_user_src_power_profile_set(set_pos_state,g_sys_pd_info.alt_sink_maxpos);
				   }

				  if(alt_sink_int_flag)
				  {

					  if (sys_cfg_dbg_get() > SYS_DEBUG_LEVEL_2)
					  {
						  printf("al dr swap_req\r\n");
					   }
					  if(PE_SNK_READY == pe_state_get())
					  {

						     dpm_source_cap_change_set(TRUE);

							 sys_alt_vbus_c1en(FALSE);
							 dpm_pr_swp_req_set(TRUE);
							/* if ((!dpm_pr_swp_req_get()) && (!dpm_prs_req_rejected_get()))
							 {
								 dpm_pr_swp_req_set(TRUE);
								 if (sys_cfg_dbg_get()) puts("1:SNK to SRC");
							 }
							 if ((dpm_prs_req_rejected_get()) &&
								 (!pe_error_recovery_directed_get()))
							 {
								 pe_error_recovery_directed_set(TRUE);
								 dpm_prs_req_rejected_set(FALSE);
								 if (sys_cfg_dbg_get()) puts("PRS rej1");
							  }*/

					  }
					alt_sink_int_flag = 0;
				   }


			}
#endif





        if (g_sys_pd_info.sys_initializing)
	    {
#if SYS_LED_ENABLED  /* modified by James Gan - 2019-11-22 */

            sys_pd_init_display();
#else

            sys_init_config(); 

#endif /* #if SYS_LED_ENABLED */
        }
        else 
        {

        	sys_pd_uplink_info_update();

#if 1
             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 < 3) &&
                   (!(dpm_drs_req_rejected_get())) &&
                   (dpm_dfp_mode_get())  &&
                   ((pe_ps_ready_start_time_get()) &&
                   ((u32_t)(now() - pe_ps_ready_start_time_get()) > 1000000UL)))
                {

               	  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() > SYS_DEBUG_LEVEL_1) 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() > SYS_DEBUG_LEVEL_1) printf("========DR swap requested, cnt=%bu.\n", g_sys_pd_info.dr_swap_cnt);
                       g_sys_pd_info.dr_swap_cnt++;
                   }
               }
#endif






            // read status reg
           // sys_bat_status_reg_set(SYS_BAT_REG_GET(STATUS_REG));
            //read state
#if 0
            if(g_sys_pd_info.usbc_power_ctrl_en)
            {
                sys_mcu_charge_discharge_ctrl();

            }
#endif
            // C1 over vbus check
            //sys_usbc_vbus_ocp_hanler();

              // C1 over voltage or short protection check
            if ((dpm_vbus_source_en_get()) &&
                (dpm_cable_detect_done_get()) && 
                (!dpm_source_ocp_flag_get()) &&
                (dpm_current_pwr_mode_get()) && 
                (!pe_hard_reset_in_prog()) && 
                (!dpm_hard_reset_req_get()) && 
                (!pe_prs_in_prog_get()) && 
                (((pe_ps_ready_start_time_get()) && ((u32_t)(now() - pe_ps_ready_start_time_get()) > 2000000UL))||
                ((!pe_pd_connected_get())&&(pe_state_get()!= PE_SRC_TRANSIT_TO_DEFAULT))) &&
                (dpm_src_ocp_vbus_drop_check()))
            {
                if(!g_sys_pd_info.ovp_start_tick)
                {
                    g_sys_pd_info.ovp_start_tick = g_sys_pd_info.continuous_timer_tick;
                } 
            }
            else
            {
                g_sys_pd_info.ovp_start_tick = 0;
            }
            if(g_sys_pd_info.ovp_start_tick &&
                ((g_sys_pd_info.continuous_timer_tick - g_sys_pd_info.ovp_start_tick) > 20))
            {
                g_sys_pd_info.ovp_start_tick = 0;
              //  sys_gpio_pmic_pstop_set(FALSE);
                sys_gpio_vbus_en_set(FALSE);
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pd_qc_led_off();
                dpm_source_ocp_flag_set(TRUE);
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
                if (g_sys_pd_info.ocp_restore_cnt < 1)
                {
                    g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
                }
                else
                {
                    dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
                    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
                }
                
#if CLI_ENABLED
        		if (sys_cfg_dbg_get()) puts("Short Protection\n");
#endif /* CLI_ENABLED */

            }
             // C1 over current check 
            if ((dpm_vbus_source_en_get()) && 
                (sys_pd_ibus_over_check())&&
                (!pe_hard_reset_in_prog())&&
                (!pe_prs_in_prog_get())&&
                (!dpm_hard_reset_req_get()))
            {
                
               // sys_gpio_pmic_pstop_set(FALSE);
                sys_gpio_vbus_en_set(FALSE);
                dpm_vbus_source_en_set(FALSE);
                sys_gpio_pd_qc_led_off();
                dpm_source_ocp_flag_set(TRUE);
                sys_pd_led_state_set(SYS_PD_LED_STATE_FLASH_FAST);
                if (g_sys_pd_info.ocp_restore_cnt < 1)
                {
                    g_sys_pd_info.ocp_start_tick = g_sys_pd_info.continuous_timer_tick;
                }
                else
                {
                    dpm_ctrl_state |= DPM_EX_MCU_CTRL_REG_DCHG_OCP_SET;
                    dpm_ctrl_mcu_set_state &= DPM_EX_MCU_SET_STA_REG_DISCHG_MASK;
                }
            }
            //c1 ibus ocp
            //sys_usbc_ibus_ocp();
          //  sys_bat_vbat_update();

            g_sys_bat_info.current_ibat_val = sys_bat_ibat_val_get();
            g_sys_pd_info.vbus_current = sys_usbc_vbus_get();
            g_sys_pd_info.ibus_current = sys_bat_ibus_val_get();
            g_sys_pd_info.c1_current_pwr = g_sys_pd_info.vbus_current * g_sys_pd_info.ibus_current / 1000000;
#if SYS_POWER_BANK_ENABLED
            
#if 0
            //qc led 
            sys_qc_led_ctr();
#endif             
            // Dead battery checking
            sys_deadbattery_protection();


            // process every 200ms
            if (0 == (g_sys_pd_info.continuous_timer_tick & 0x1))
            {
                
                // get ibat value
               detect_current_direction();
#if SYS_POWER_SOURCE_NO_CURRENT_HRST

               pd_hard_reset_need_check();
#endif
                // check capacity
               sys_bat_capacity_check();

                // power down detection 
#if SYS_POWER_BANK_POWER_DOWN_DETECT
                powerkey_event_hander();   
#endif

#if SYS_USBA_ENABLED
                // usb-a current check
                usba_current_check();
#endif
#if SYS_POWER_BANK_AUTO_POWER_DOWN_EN
                //auto off
                chip_auto_power_off();
#endif                
                dead_battery_exit_checkout();
#if 0
                if (g_sys_pd_info.usbc_power_ctrl_en)
                {
                    dpm_ex_mcu_ctrl_set(dpm_ctrl_state);
                    dpm_ex_mcu_set_sta_set(dpm_ctrl_mcu_set_state);
                }  
#endif
                sys_pd_check_epr();
            }


            if ((g_sys_pd_info.continuous_timer_tick & 3) == 0)
            {
#if SYS_OVERTEMP_DECTION_ENABLED  
                sys_ntc_temp_protection();

#endif /* SYS_OVERTEMP_DECTION_ENABLED */
                
            }

            // Current compensation every 500ms
            if ((g_sys_pd_info.continuous_timer_tick % 5) == 0)
            {
                //current and volt adjust
                usbc_volt_adjust();
                
#if (SYS_LED_ENABLED||SYS_SMG_DISPLAY_ENABLED)                
                
                sys_pd_display_state_machine();
    	        sys_pd_display_process();
                
#endif // handle digit or led display  
#if 0
                if (g_sys_pd_info.usbc_power_ctrl_en)
                {
                    dpm_ex_mcu_vbat_set(sys_bat_current_vbat_val_get());
                
                    dpm_ex_mcu_ibat_set(sys_bat_current_ibat_val_get());
                    
                    dpm_ex_mcu_vbus_set(g_sys_pd_info.vbus_current);
                    
                    dpm_ex_mcu_ibus_set(g_sys_pd_info.ibus_current);
                }
#endif
            }

            // Check the capacity every 800 ms 
            if (0 == (g_sys_pd_info.continuous_timer_tick & 0x7))
            {
                battery_charging_isfull();
            }
            if (0 == (g_sys_pd_info.continuous_timer_tick % 20))
            {
                sys_pd_power_policy_process(FALSE);
            }
            
#if SYS_USBA_ENABLED
            // usb-a insert detection
            {
                if ((!g_sys_pd_info.p60c_otp_flag) && 
                    (!g_sys_pd_info.m10c_otp_flag) && 
                    (!dpm_port_dead_battery_get()))
                {

                    g_sys_pd_info.usba_vbus_val = sys_usba1_vbus_get();
                    
                    
                    sys_small_current_mode();
#if  0                  
                    sys_usba_indet_detect();
#endif
                    sys_usba_unload();
                        
                    //sys_usba_ocp_protection();
                   
                }
            }
#endif
#endif /* SYS_POWER_BANK_ENABLED */

            // C1 VBUS check
            sys_usbc_vbus_check();
            // ocp restore
            //sys_usbc_ocp_restore();

        }

        // 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_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
#define SYS_PD_STD_DP_SID0              0XFF00
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;

                   // if(p_vdm_specific->vdm_head.svid == SYS_PD_STD_DP_SID0)
                    //	p_vdm_specific->vdm_head.svid =  SYS_PD_STD_DP_SID;

                    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;
                    //g_sys_pd_info.attention_req_flg = TRUE;
                    if (!g_sys_pd_info.switch_games_mode)
                    {
                        if (alt_holdout_get())
                        {
                            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; //0
                            /*-----------------------*/
                        }
                        else
                        {
                            // 使能 GPIO0 中断
                            drv_gpio_intr_polar_set(DSVL_HPDOUT, 1);
                            drv_gpio_intr_en_set(DSVL_HPDOUT, 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)
            {
            	dpm_rx_vdm_req_vid_set(p_vdm_specific->vdm_head.svid); //ma 修补联想电脑

                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))
                {



                	//g_sys_pd_info.attention_req_flg = TRUE;



                    if (dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_C)
                    {
                        if (!dpm_orient_select_get())  //CC1
                        {

                        	alt_dsvl171_setmode(e_dp_pass_c);
                        }
                        else   //CC2
                        {
                        	alt_dsvl171_setmode(e_dp_pass_d);

                        }
                    }
                    else if (dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_D)
                    {
                        if (!dpm_orient_select_get())
                        {
                        	alt_dsvl171_setmode(e_dp_pass_a);

                        }
                        else
                        {
                        	alt_dsvl171_setmode(e_dp_pass_b);

                        }
                    }
                    else if(dp_ufp_rx_cfg->cfg_ufp_u_ass == SYS_DP_ASS_E)
                    {

                    }

                    rtc_delay_us(300);


                    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_disc_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_DISCOVER_MODE_t *P_VDM_DISCOVER_MODE = (UPD_DATA_MSG_VDM_DISCOVER_MODE_t *)p_msg;
    if (dir == PRL_MSG_DIR_TX)
    {
      
    }
    else
    {
        if (P_VDM_DISCOVER_MODE->vdm_head.svid == 0x057e)
        {
            dpm_vdm_resp_ignore_set(TRUE);
            printf("no enter 0x057e\n");
        }
        else if (usbpd_cfg_port_vdm_modal_opr_supp_get() && 
            ((P_VDM_DISCOVER_MODE->vdm_head.svid == 0xff01)||
            (P_VDM_DISCOVER_MODE->vdm_head.svid == usbpd_cfg_vd_usb_vid_get())))
        {
            dpm_vdm_ack_set(TRUE);
            dpm_vdm_nak_set(FALSE);
        }
        else 
        {
            dpm_vdm_ack_set(FALSE);
            dpm_vdm_nak_set(TRUE);
        }

        // to fix ellisys IOP issue
        rtc_delay_us(VENDOR_DEFINE_ACK_DELAY_TIME);

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

    }
}
#define SWITCH_USB_VID  0x057E

void sys_pd_prl_msg_vdm_enter_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_ENTER_MODE_t *P_VDM_ENTER_MODE = (UPD_DATA_MSG_VDM_ENTER_MODE_t *)p_msg;
    if (dir == PRL_MSG_DIR_RX)
    {
        if (usbpd_cfg_port_vdm_modal_opr_supp_get() &&( 
            (P_VDM_ENTER_MODE->vdm_head.svid == usbpd_cfg_vd_usb_vid_get())||
            (P_VDM_ENTER_MODE->vdm_head.svid == 0xff01))&& 
            (P_VDM_ENTER_MODE->vdm_head.obj_pos == DEFAULT_USB_MODE_POS))
        {
            dpm_mode_entered_set(TRUE);
            if (P_VDM_ENTER_MODE->vdm_head.svid == SWITCH_USB_VID)
            {
                g_sys_pd_info.switch_games_mode = TRUE;
            }
        }
        else 
        {
            dpm_mode_enter_nak_set(TRUE);
        }
#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 */
    }
    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 SYS_DEBUG_ENABLED
        if (usbpd_cfg_dbg_get()) 
        {
            printf("VDM Unstructured RX Hook: 0x%04X 0x%08X 0x%08X 0x%08X\n", 
                *(u16_t *)&rx_data[0], *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN], 
                *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN], 
                *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN+4]);
        }
#endif /* SYS_DEBUG_ENABLED */
    UPD_DATA_MSG_VDM_UNSTRUCTURED_t *p_vdm_unstruct = (UPD_DATA_MSG_VDM_UNSTRUCTURED_t *)p_msg;
    if (PRL_MSG_DIR_RX == dir)
    {
        if (SWITCH_USB_VID == p_vdm_unstruct->vdm_head.svid)
        {
            g_sys_pd_info.rx_vdm_unstruct_obj1 = *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN];
            g_sys_pd_info.rx_vdm_unstruct_obj2 = *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN];
            g_sys_pd_info.rx_vdm_unstruct_obj3 = *(u32_t *)&rx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN+UPD_MSG_DATA_OBJ_SIZE];

            if (g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00160100)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_00;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());
                
            }
            else if(g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x000b0100)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_01;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());
            }
            else if (g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00180100)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_02;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());
            }
            else if((g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00010101) && (g_sys_pd_info.rx_vdm_unstruct_obj3 == 0x80140000))
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_03;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());

            }
            else if(g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00100100)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_04;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());

            }
            else if(g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00060100)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_05;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());
            }
            else if(g_sys_pd_info.rx_vdm_unstruct_obj2 == 0x00200101)
            {
                g_sys_pd_info.tx_vdm_unstruct_type = VDM_UNSTRUCTURED_SWITCH_06;
                prl_msg_tx(VDM_UNSTRUCTURED_MSG, dpm_msg_sop_type_get());

            }
            else
            {
                pe_unsupported_msg_received_set(TRUE);
            }

        }
        else
        {
            pe_unsupported_msg_received_set(TRUE);
        }
       
    }
    else
    {
        
        p_vdm_unstruct->vdm_head.svid = usbpd_cfg_vd_usb_vid_get();
        p_vdm_unstruct->vdm_head.type = 0;
        switch (g_sys_pd_info.tx_vdm_unstruct_type)
        {
            case VDM_UNSTRUCTURED_SWITCH_00:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00170200;
                p_vdm_unstruct->data_objs.u32[1] = 0x00000000;
                p_vdm_unstruct->head.data_obj_num = 3;
                break;
            case VDM_UNSTRUCTURED_SWITCH_01:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x000c0200;
                p_vdm_unstruct->data_objs.u32[1] = 0x000015d0;
                p_vdm_unstruct->head.data_obj_num = 3;
                break;
            case VDM_UNSTRUCTURED_SWITCH_02:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00190200;
                p_vdm_unstruct->data_objs.u32[1] = 0x026b0b10;
                p_vdm_unstruct->head.data_obj_num = 3;
                break;
            case VDM_UNSTRUCTURED_SWITCH_03:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00020201;
                p_vdm_unstruct->data_objs.u32[1] = 0x80140000;
                p_vdm_unstruct->head.data_obj_num = 3;

                //g_sys_pd_info.dp_mode_flg = TRUE;
                //g_sys_pd_info.attention_req_flg = TRUE;
                if (alt_holdout_get())
                {
                    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; //0
                    /*-----------------------*/
                }
                else
                {
                    // 使能 GPIO0 中断
                    drv_gpio_intr_polar_set(DSVL_HPDOUT, 1);
                    drv_gpio_intr_en_set(DSVL_HPDOUT, TRUE);
                    sys_pd_hpd_start_time_set(now());
                }
                break;
            case VDM_UNSTRUCTURED_SWITCH_04:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00110200;
                p_vdm_unstruct->data_objs.u32[1] = 0x000015cd;
                p_vdm_unstruct->head.data_obj_num = 3;
                break;
            case VDM_UNSTRUCTURED_SWITCH_05:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00070200;
                p_vdm_unstruct->data_objs.u32[1] = 0x001a1002;
                p_vdm_unstruct->head.data_obj_num = 3;
                break;
             case VDM_UNSTRUCTURED_SWITCH_06:
                p_vdm_unstruct->vdm_head.content = 0x0040;
                p_vdm_unstruct->data_objs.u32[0] = 0x00210200;
                p_vdm_unstruct->head.data_obj_num = 2;
                break;
            default:
                break;

        }
#if SYS_DEBUG_ENABLED
            if (usbpd_cfg_dbg_get()) 
            {
                printf("VDM Unstructured TX Hook: 0x%04X 0x%08X 0x%08X 0x%08X\n", 
                    *(u16_t *)&tx_data[0], *(u32_t *)&tx_data[UPD_MSG_HEAD_LEN], 
                    *(u32_t *)&tx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN], 
                    *(u32_t *)&tx_data[UPD_MSG_HEAD_LEN+UPD_MSG_VDM_HEAD_LEN+4]);
            }
#endif 
    }
}
#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_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;

    }
}

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

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

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

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

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






void sys_pd_prl_msg_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;
#if 1
    if(sys_alt_a_to_c_get() == FALSE)
    {
        g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp = SYS_DP_ASS_D;
        g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp = SYS_DP_ASS_D;
        sys_alt_usbc_to_a(TRUE);
    }
    else
    {
        sys_alt_usbc_to_a(FALSE);
        g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp = SYS_DP_ASS_C;//|SYS_DP_ASS_D;
        g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp = SYS_DP_ASS_C;
    }
    g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp = SYS_DP_ASS_C|SYS_DP_ASS_D;
#else
    g_sys_pd_info.ufp_d_cap.dfp_d_ass_supp = SYS_DP_ASS_D;
    g_sys_pd_info.ufp_d_cap.ufp_d_ass_supp = SYS_DP_ASS_D;
    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;
#endif


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

#if SYS_QUICK_CHARGE_ENABLED
    sys_qc_init();
#endif

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

    usbpd_snk_transit_to_new_power_hook_set(sys_pd_sink_transit_to_new_power_hook);
    usbpd_src_transit_to_new_power_hook_set(sys_pd_source_transit_to_new_power_hook);

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

    usbpd_hook_with_return_set(src_vbus_en, sys_pd_vbus_source_en_get);
    usbpd_hook_with_return_set(discharge_en, sys_pd_vbus_discharge_en_get);
    usbpd_hook_with_return_set(cc1_vconn_en, sys_pd_cc1_vconn_en_get);
    usbpd_hook_with_return_set(cc2_vconn_en, sys_pd_cc2_vconn_en_get);
    usbpd_hook_with_return_set(c1_vbus_volt, sys_usbc_vbus_get);
    
    usbpd_event_hook_set(prs_started, sys_pd_prs_started_hook);
    usbpd_event_hook_set(prs_completed, sys_pd_prs_completed_hook);
    usbpd_event_hook_set(drs_started, sys_pd_drs_started_hook);
    usbpd_event_hook_set(drs_completed, sys_pd_drs_completed_hook);
    usbpd_event_hook_set(vcs_started, sys_pd_vcs_started_hook);
    usbpd_event_hook_set(vcs_completed, sys_pd_vcs_completed_hook);
    usbpd_event_hook_set(power_change_req, sys_pd_power_change_req_hook);
    usbpd_event_hook_set(idle, sys_pd_idle_hook);
    usbpd_event_hook_set(vdm_disc_ident_ack_received, sys_pd_vdm_disc_ident_ack_received_hook);
    usbpd_event_hook_set(prl_msg_received, sys_pd_prl_msg_received_hook);
    usbpd_event_hook_set(prl_msg_sent, sys_pd_prl_msg_sent_hook);
    usbpd_prl_msg_hook_set(source_capabilities, (v_func_args_ptr_t)sys_pd_prl_msg_src_cap_hook);
    usbpd_prl_msg_hook_set(request, (v_func_args_ptr_t)sys_pd_prl_msg_request_hook);

    usbpd_prl_msg_hook_set(vdm_attention, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_attention_hook);
    usbpd_prl_msg_hook_set(vdm_unstructured, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_unstructured_hook);

	usbpd_prl_msg_hook_set(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(vdm_disc_mode_req, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_disc_mode_req_hook);
    usbpd_prl_msg_hook_set(vdm_enter_mode_req, (v_func_args_ptr_t)sys_pd_prl_msg_vdm_enter_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);
}


