/**
 * \file    cli_cmd_usbpd.c
 * \brief   USB PD CLI command definistions
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-02-24
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-02-24  Original Creation
 * 
 */


#include <stdarg.h>
#include "cli_engine.h"
#include "cli_cmd_base.h"
#include "cli_cmd_usbpd.h"

#if CLI_ENABLED
#if USB_PD_MODULE_ENABLED

#include "libc.h"
#include "drivers.h"
#include "usbpd.h"
#include "sys_config.h"
#include "sys_pd_config.h"
#include "pe_state.h"
#include "prl_tcpm.h"
#include "sys_gpio.h"
#include "sys_pd_hook.h"
#if (SYS_OLED_DISPLAY_ENABLED)
#include "sys_oled_display.h"
#endif
#if SYS_SMG_DISPLAY_ENABLED
#include "sys_smg_display.h"
#endif /* SYS_SMG_DISPLAY_ENABLED */
#if SYS_QUICK_CHARGE_ENABLED
#include "sys_qc_hook.h"
#endif /* SYS_QUICK_CHARGE_ENABLED */

/** Cable type definition */
const char * const g_cli_sys_cfg_cbl_type[CABLE_TYPE_END] = {
    "Type-A", //
    "Type-B", //
    "Type-C"
    };

/** UFP Product type definition */
const char * const g_cli_sys_cfg_prod_type[UPD_PRODUCT_END] = {
    "N/A",
    "HUB",
    "Peripheral",
    "PSD",
    "RESV",
    "AMA",
    "VPD"
    };

/** Product type definition */
const char * const g_cli_sys_cfg_cbl_prod_type[UPD_CBL_PROD_END] = {
    "N/A",
    "RESV1",
    "RESV2",
    "Passive Cable",
    "Active Cable"
    };


/** Product type definition */
const char * const g_cli_sys_cfg_dfp_prod_type[UPD_DFP_PROD_END] = {
    "N/A",
    "HUB",
    "Host",
    "Power Brick",
    "AMC"
    };


/** System role definition */
const char * const g_cli_sys_cfg_sys_role[PD_ROLE_END] = {
    "Consumer",
    "Provider",
    "Provider/Consumer",
    "Consumer/Provider",
    "Cable Plug",
    "Capture"
    };

/** Default power role */
const char * const g_cli_sys_cfg_def_pr[POWER_ROLE_END] = {
    "SNK",
    "SRC",
    "DRP"
    };

/** Default data role */
const char * const g_cli_sys_cfg_def_dr[USB_DATA_ROLE_END] = {
    "UFP",
    "DFP",
    "DRD"
    };

#if SYS_QUICK_CHARGE_ENABLED
/** QC Version */
const char * const g_cli_qc_ver_str[4] = {
    "V2.0",
    "V3.0",
    "V4.0",
    "N/A"
    };
#endif /* SYS_QUICK_CHARGE_ENABLED */

/* Command definitions */
#if CLI_INCLUDE_PDINFO
void cli_cmd_pdinfo(void)
{
    u32_t type, curr_pwr_mode;
    bool_t detected;

    printf("\n %-26s: %s\n", "Testing Mode", g_cli_onoff_str[usbpd_cfg_test_mode_get()]);
    printf(" %-26s: %s\n", "Capture Mode", g_cli_onoff_str[usbpd_cfg_capture_mode_get()]);

#if SYS_OLED_DISPLAY_ENABLED
    printf(" %-26s: %s\n", "OLED Display", g_cli_onoff_str[usbpd_cfg_oled_display_mode_get()]);
#endif /* SYS_OLED_DISPLAY_ENABLED */

    printf(" %-26s: %s\n", "Manufacturer Info", usbpd_cfg_mfr_info_get());

    if (!usbpd_cfg_capture_mode_get())
    {
        printf(" USB Vendor Defined:\n"); 
        printf("  %-25s: 0x%X\n", "SVID", usbpd_cfg_vd_usb_svid_get());
        printf("  %-25s: 0x%X\n", "VID", usbpd_cfg_vd_usb_vid_get());
        printf("  %-25s: 0x%X\n", "BCD", usbpd_cfg_vd_usb_bcd_device_get());
        printf("  %-25s: 0x%X\n", "PID", usbpd_cfg_vd_usb_prod_id_get());
        printf("  %-25s: 0x%X\n", "TID", usbpd_cfg_vd_usb_tid_get());
    }

    curr_pwr_mode = dpm_current_pwr_mode_get();
    detected = dpm_cable_detect_done_get();

    printf("\n %-26s: %s\n", "Cable Type", g_cli_sys_cfg_cbl_type[usbpd_cfg_port_cbl_type_get()]);
    printf(" %-26s: %s\n", "Product Type", g_cli_sys_cfg_prod_type[(u8_t)usbpd_cfg_prod_type_get()]);
    printf(" %-26s: %s\n", "Power Limited", g_cli_true_str[usbpd_cfg_port_power_limited_get()]);
    printf(" %-26s: %s\n\n", "System Role", g_cli_sys_cfg_sys_role[usbpd_cfg_port_def_pdr_get()]);
    if (!usbpd_cfg_capture_mode_get())
    {
        if (FALSE == usbpd_cfg_port_no_pd_mode_get())
        {
            printf(" %-26s: %s\n", "PD Spec Rev", (SPEC_REVISION_3_0 == usbpd_cfg_port_spec_rev_get()) ? "3.0" :
                ((SPEC_REVISION_2_0 == usbpd_cfg_port_spec_rev_get()) ? "2.0 (V1.1)" : "1.0"));
            printf(" %-26s: %u\n", "PD Retry Count", usbpd_cfg_port_retry_cnt_get());
            if (PD_ROLE_CABLE_PLUG == usbpd_cfg_port_def_pdr_get())
            {
                printf(" %-26s: %s\n", "Local VCONN Detected", g_cli_true_str[dpm_vcon_detected()]);
            }
        }
        else
        {
            printf(" %-26s: Disabled\n", "PD Mode");
        }
#if SYS_QUICK_CHARGE_ENABLED
        printf(" %-26s: %s\n", "Quick Charge Enabled", g_cli_true_str[usbpd_cfg_port_quick_charge_en_get()]);
        printf(" %-26s: %s\n", "Quick Charge Version", g_cli_qc_ver_str[usbpd_cfg_port_quick_charge_ver_get()]);
#endif
    }
    if (PD_ROLE_CABLE_PLUG == usbpd_cfg_port_def_pdr_get())
    {
        printf(" %-26s: %s\n", "SOP\" Controller Present", g_cli_true_str[usbpd_cfg_port_vdm_sop2_ctrler_pres_get()]);
        printf(" %-26s: %s\n", "VBUS Current Capability", (usbpd_cfg_port_vdm_vbus_curr_cap_get() == VBUS_CURR_HANDLING_CAP_5A) ? "5A" : "3A");
    }
    if ((!usbpd_cfg_cable_plug_get()) && (!usbpd_cfg_capture_mode_get()))
    {
        printf(" %-26s: %s\n", "VDM", g_cli_onoff_str[usbpd_cfg_port_vdm_en_get()]);
        printf(" %-26s: %s\n", "VDM SRC Startup", g_cli_onoff_str[usbpd_cfg_port_vdm_src_startup_en_get()]);
        printf(" %-26s: %s\n", "VDM Modal Supported", g_cli_true_str[usbpd_cfg_port_vdm_modal_opr_supp_get()]);
        printf(" %-26s: %s\n", "VBUS Checking", g_cli_true_str[usbpd_cfg_port_vbus_check_get()]);
        if ((POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            || (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get()))
        {
            printf(" %-26s: 0x%X/0x%X\n", "SNK vRd Min/Max", usbpd_cfg_port_vrd_min_snk_get(), usbpd_cfg_port_vrd_max_snk_get());
        }
        if ((POWER_ROLE_SOURCE == usbpd_cfg_port_def_pr_get())
            || (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get())) 
        {
            printf(" %-26s: 0x%X/0x%X\n", "SRC vRd Min/Max", usbpd_cfg_port_vrd_min_src_get(), usbpd_cfg_port_vrd_max_src_get());
            printf(" %-26s: 0x%X/0x%X\n", "vRa Min/Max", usbpd_cfg_port_vra_min_get(), usbpd_cfg_port_vra_max_get());
            printf(" %-26s: 0x%X\n", "vOpen", usbpd_cfg_port_vopen_get());
        }
        printf(" %-26s: 0x%X/0x%X\n", "ADC Result CC1/CC2", drv_adc_read_multi(DRV_ADC_CHN_CC1,DPM_CC_READING_COUNT),
            drv_adc_read_multi(DRV_ADC_CHN_CC2,DPM_CC_READING_COUNT));

        printf(" %-26s: %s/%s\n", "Default Role Power/Data", g_cli_sys_cfg_def_pr[usbpd_cfg_port_def_pr_get()], g_cli_sys_cfg_def_dr[usbpd_cfg_port_def_dr_get()]);
        if (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get())
        {
            printf(" %-26s: %s\n", "Try Source", g_cli_true_str[usbpd_cfg_port_try_src_get()]);
        }
        printf(" %-26s: %s/%s\n\n", "Current Role Power/Data", detected ? g_cli_sys_cfg_def_pr[curr_pwr_mode] : "NA", detected ? g_cli_sys_cfg_def_dr[dpm_dfp_mode_get()] : "NA");

        printf(" %-26s: %s\n", "Cable Connected", g_cli_true_str[detected]);
        if (POWER_MODE_SINK == curr_pwr_mode)
        {
            printf(" %-26s: %s\n", "VBUS Detected", g_cli_true_str[dpm_vbus_detected()]);
        }
        printf(" %-26s: %lu mV\n", "VBUS Voltage", dpm_vbus_volt_get());
        printf(" %-26s: %lu mA\n", "IBUS Current", sys_pd_ibus_get());
        printf(" %-26s: %s\n", "Orientation", detected ? (dpm_orient_select_get() ? "CC2" : "CC1" ) : "NA");
        printf(" %-26s: %s\n", "EMCA Detected", g_cli_true_str[dpm_cbl_plug_detected_get()]);
        printf(" %-26s: %s\n", "VCONN Sourcing", g_cli_true_str[dpm_presently_vconn_source_get()]);
        printf(" %-26s: %s\n", "SOP\" Controller Present", dpm_cbl_plug_detected_get() ? g_cli_true_str[dpm_vdm_sop2_present_get()] : "NA");
        if (!usbpd_cfg_port_no_pd_mode_get())
        {
            if (POWER_ROLE_SOURCE != usbpd_cfg_port_def_pr_get())
            {
                printf(" %-26s: %lu mV / %lu mA\n", "Operating V/I", (usbpd_cfg_port_snk_pwr_volt_get()*VOLTAGE_DIV), (usbpd_cfg_port_snk_pwr_curr_get()*CURRENT_DIV));
            }
            if (POWER_ROLE_SINK != usbpd_cfg_port_def_pr_get())
            {
                printf(" %-26s: %lu\n", "Power Profile", usbpd_cfg_port_src_fixed_pwr_prof_get());
                for (type = 0; type < CFG_MAX_PWR_CAP_NUM; type++)
                {
                    if (POWER_SUPPLY_TYPE_PPS == usbpd_cfg_port_src_pwr_supply_type_get(type))
                    {
                        if (detected && curr_pwr_mode && ((type+1) == dpm_src_obj_pos_get()))
                        {
                            printf("    %lu-%lu mV / %lu mA (Active)\n", (usbpd_cfg_port_src_pps_pwr_min_volt_get(type)*VOLTAGE_PPS_DIV), 
                                (usbpd_cfg_port_src_pps_pwr_max_volt_get(type)*VOLTAGE_PPS_DIV), 
                                (usbpd_cfg_port_src_pps_pwr_max_curr_get(type)*CURRENT_PPS_DIV));
                        }
                        else {
                            printf("    %lu-%lu mV / %lu mA\n", (usbpd_cfg_port_src_pps_pwr_min_volt_get(type)*VOLTAGE_PPS_DIV), 
                                (usbpd_cfg_port_src_pps_pwr_max_volt_get(type)*VOLTAGE_PPS_DIV), 
                                (usbpd_cfg_port_src_pps_pwr_max_curr_get(type)*CURRENT_PPS_DIV));
                        }
                    }
                    else {
                        if (usbpd_cfg_port_src_fixed_pwr_curr_cap_get(type))
                        {
                            if (detected && curr_pwr_mode && ((type+1) == dpm_src_obj_pos_get()))
                            {
                                printf("    %lu mV / %lu mA (Active)\n", (usbpd_cfg_port_src_fixed_pwr_volt_cap_get(type)*VOLTAGE_DIV), 
                                    (usbpd_cfg_port_src_fixed_pwr_curr_cap_get(type)*CURRENT_DIV));
                            }
                            else {
                                printf("    %lu mV / %lu mA\n", (usbpd_cfg_port_src_fixed_pwr_volt_cap_get(type)*VOLTAGE_DIV), 
                                    (usbpd_cfg_port_src_fixed_pwr_curr_cap_get(type)*CURRENT_DIV));
                            }
                        }
                    }
                }
            }
        }
    }
    else if (usbpd_cfg_capture_mode_get()) 
    {
        printf(" %-26s: %lu mV\n", "VBUS Voltage", dpm_vbus_volt_get());
    }
    printf("\n");
}
#endif

static int str_to_sop_type(char *str)
{
    int type = MSG_SOP_TYPE_END;

    if (!str)
        return type;

    if (0 == strcmp("sop", str))
    {
        type = MSG_SOP_TYPE_SOP;
    }
    else if (0 == strcmp("sop1", str))
    {
        type = MSG_SOP_TYPE_SOPP;
    }
    else if (0 == strcmp("sop2", str))
    {
        type = MSG_SOP_TYPE_SOPPP;
    }
    else if (0 == strcmp("sop1d", str))
    {
        type = MSG_SOP_TYPE_SOPP_DBG;
    }
    else if (0 == strcmp("sop2d", str))
    {
        type = MSG_SOP_TYPE_SOPPP_DBG;
    }

    return type;
}


#if CLI_INCLUDE_MSG
extern void pe_src_send_soft_reset();
extern void pe_snk_send_soft_reset();
int cli_msg_tx_len = 0;
#endif


const char * const g_cli_cmd_usbpd_help[] = {
#if CLI_INCLUDE_HELP
    "PD sub commands",
#if CLI_ENABLED_VERBOSE_HELP
    "",
    "{test} {on|off}",
    "{runtime} {ldo2} <value>",
    "{runtime} {rd} <value>",
    "{runtime} {ccfreq} <value>",
    "{init} {ldo1} <value>",
    "{init} {ldo2} <value>",
    "{init} {cces} <value>",
    "{init} {halfbit} <period>",
    "{init} {rxfilter} <value>",
    "{init} {stc} <value>",
    "{init} {ccref} <value>",
#if VENDOR_DEFINE_ENABLED
    "{svid} <value>",
    "{vid} <value>",
    "{bcd} <value>",
    "{pid} <value>",
    "{tid} <value>",
#endif /* VENDOR_DEFINE_ENABLED */
    "{mfr} <string>",
#if SYS_SMG_DISPLAY_ENABLED
	"{smg} {on|off}",
	"{smg} <value>",
#endif
#if SYS_OLED_DISPLAY_ENABLED
	"{oled} {on|off}",
#endif
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
    "{capture} {on|off}",
#endif
#if (CABLE_PLUG_ENABLED)
    "{cbl} {on|off}",
#endif
    "{on|off|r2|r3}",
    "{retry} <count>",
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
    "{pr} {drp|src|snk}",
#endif
    "{dr} {drd|dfp|ufp}",
    "{cs} {80|180|330}",
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
    "{trysrc} {on|off}",
#endif
#if 1  /* deleted by James Gan - 2017-10-25 */
    "{vrdmin-src} <value>",
    "{vrdmax-src} <value>",
    "{vrdmin-snk} <value>",
    "{vrdmax-snk} <value>",
    "{vramin} <value>",
    "{vramax} <value>",
    "{vopen} <value>",
#endif /* #if 0 */
#if SYS_QUICK_CHARGE_ENABLED
    "{qc} {v2|v3|off}",
#endif /* SYS_QUICK_CHARGE_ENABLED */
    "{vbus-check} {on|off}",
#if VCONN_ENABLED
    "{vconn} {on|off}",
#endif
    "{power-limit} {on|off}",
    "{pwm} {on|off}",
    "{pwm-per} <value>",
    "{pwm-fixed} {5v|9v|12v|15v|20v} <duty>",
    "{profile} <id>",
    "\t Power ID:",
    "\t   1: 0.5W-FIX:5V0.1A",
    "\t   2: 15W-FIX:5V3A",
    "\t   3: 18W-FIX:5V3A,9V2A,12V1.5A,15V1.2A",
    "\t   4: 18W-PPS:5V3A,9V2A,3.3-5.9V3A,3.3-11V2A",
    "\t   5: 30W-FIX:5V3A,9V3A,12V2.5A,15V2A",
    "\t   6: 30W-PPS:5V3A,9V3A,15V3A,3.3-11V3A,3.3-16V2A",
    "\t   7: 45W-FIX:5V3A,9V3A,12V3A,15V3A,20V2.25A",
    "\t   8: 45W-PPS:5V3A,9V3A,15V3A,20V2.25A,3.3-21V3A",
    "\t   9: 60W-FIX:5V3A,9V3A,12V3A,15V3A,20V3A",
    "\t   10:60W-PPS:5V3A,9V3A,15V3A,20V3A,3.3-21V3A",
    "\t   11: 65W-FIX:5V3A,9V3A,12V3A,15V3A,20V3.25A",
    "\t   12: 65W-PPS:5V3A,9V3A,15V3A,20V3.25A,3.3-21V3.25A",
    "\t   13: 80W-FIX:5V3A,9V3A,12V3A,15V3A,20V4A",
    "\t   14: 80W-PPS:5V3A,9V3A,15V3A,20V4A,3.3-21V4A",
    "\t   15: 100W-FIX:5V3A,9V3A,12V3A,15V3A,20V5A",
    "\t   16: 100W-PPS:5V3A,9V3A,15V3A,20V5A,3.3-21V5A",
    "{opr-pwr} <id>",
    "\t ID:",
    "\t   0: 5V3A",
    "\t   1: Follow src maximal",
    "\t   2: 9V2A",
    "\t   3: 12V2A",
    "\t   4: 14.8V2A",
    "\t   5: 15V2A",
    "\t   6: 20V2A",
    "\t   7: 5V0.1A",
    "\t   8: 20V5A",
#if VENDOR_DEFINE_ENABLED
    "{vdm} {off|on}",
    "{vdm-startup} {on|off}",
#if VENDOR_DEFINE_MODE_ENABLED
    "{vdm-mode} {off|on}",
#endif /* VENDOR_DEFINE_MODE_ENABLED */ 
#if (CABLE_PLUG_ENABLED)
    "{sop2} {off|on}",
    "{vcc} {3A|5A}",
#endif
    "{ss} {v2|v3g1|v3a}",
#endif /* VENDOR_DEFINE_ENABLED */
    "\t",
    "{bist-cm2} [sop|sop1|sop2|sop1d|sop2d]",
    "{bist-data} <len> <hex> [sop|sop1|sop2|sop1d|sop2d]",
#if CLI_INCLUDE_PRS
    "{prs}",
#endif /* CLI_INCLUDE_PRS */
#if CLI_INCLUDE_DRS
    "{drs}",
#endif /* CLI_INCLUDE_DRS */
#if CLI_INCLUDE_VCS
    "{vcs}",
#endif /* CLI_INCLUDE_VCS */
#if CLI_INCLUDE_GETSRC
    "{getsrc}",
#endif /* CLI_INCLUDE_GETSRC */
#if CLI_INCLUDE_GETSNK
    "{getsnk}",
#endif /* CLI_INCLUDE_GETSNK */
#if CLI_INCLUDE_GOTOMIN
    "{gotomin}",
#endif /* CLI_INCLUDE_GOTOMIN */
#if CLI_INCLUDE_NEWPWR
    "{newpwr}",
#endif /* CLI_INCLUDE_NEWPWR */
#if CLI_INCLUDE_HRST
    "{hrst}",
#endif /* CLI_INCLUDE_HRST */
#if CLI_INCLUDE_CBL_RST
    "{crst}",
#endif /* CLI_INCLUDE_CBL_RST */
#if CLI_INCLUDE_SRST
    "{srst}",
#endif /* CLI_INCLUDE_SRST */
#if CLI_INCLUDE_EXT
    "{alert} <type>",
    "\t Type of Alert",
    "\t  Bit Description",
    "\t  0   Reserved and Shall be set to zero",
    "\t  1   Battery Status Change",
    "\t      Event(Attach/Detach/charging/discharging/idle)",
    "\t  2   OCP event when set (Source only, for Sink",
    "\t      Reserved and Shall be set to zero)",
    "\t  3   OTP event when set",
    "\t  4   Operating Condition Change when set",
    "\t  5   Source Input Change Event when set",
    "\t  6   OVP event when set (Sink only, for Source",
    "\t      Reserved and Shall be set to zero)",
    "\t  7   Reserved and Shall be set to zero",
    "{get} {status|batsta|batcap|extsrc|extsnk|pps|mfr|ctry-codes|ctry-info}",
#endif /* CLI_INCLUDE_EXT */
#if CLI_INCLUDE_MSG
    "{msg} <sop-type> <hex-data> <action>",
    "\t sop-type:",
    "\t   0: SOP",
    "\t   1: SOP'",
    "\t   2: SOP\"",
    "\t   3: SOP' Debug",
    "\t   4: SOP\" Debug",
    "\t hex-data:",
    "\t   the PD message data, for example:",
    "\t     42142CB10411, means request message, length is 6 bytes",
    "\t action:",
    "\t   0: the 1st part message to be sent",
    "\t   1: the 2nd part message to be sent",
    "\t   2: the 3rd part message to be sent",
    "\t   3: the 4th part message to be sent",
    "\t   4: the 5th part message to be sent",
    "\t   5: the 6th part message to be sent",
    "\t   6: the 7th part message to be sent",
    "\t   7: the 8th part message to be sent",
    "\t   8: the 9th part message to be sent",
    "\t   x: send the message",
#endif /* CLI_INCLUDE_MSG */
#if VENDOR_DEFINE_ENABLED
    "{vdmtx} <type>",
    "\t Type:",
    "\t  0: Discover Identity",
    "\t  1: Discover SVID",
    "\t  2: Exit Mode",
    "\t  3: SOP' Discover Identity",
    "\t  4: SOP' Discover SVID",
    "\t  5: SOP' Exit Mode",
    "\t  6: Attention",
    "\t  7: SOP\" Discover Identity",
    "\t  8: SOP\" Discover SVID",
    "\t  9: SOP\" Exit Mode",
    "\t  10: SOP'D Discover Identity",
    "\t  11: SOP\"D Discover Identity",
#endif /* VENDOR_DEFINE_ENABLED */
#endif /* CLI_ENABLED_VERBOSE_HELP */
#endif /* CLI_INCLUDE_HELP */
    0,
};

extern const char * const info_msg_type[MSG_TYPE_MAX];

int cli_cmd_usbpd(int argc, char *argv[])
{
    u32_t tmp;
    char *p;

    if (argc < 2)
    {
        cli_cmd_pdinfo();
    }
    else if (0 == strcmp("state", argv[1]))
    {
	    printf(" State: \n");
        printf("  %-25s: %d\n", "PRL TX PKT", g_sys_pd_info.tx_pkt_cnt);
        printf("  %-25s: %d\n", "PRL TX state", prl_tx_state_get());
        printf("  %-25s: 0x%08X\n", "PRL TX DMA", prl_msg_tx_wptr_get());
        printf("  %-25s: 0x%08X\n", "PRL TX RPTR", prl_msg_tx_rptr_get());
        printf("  %-25s: 0x%08X\n", "PRL TX WPTR", prl_msg_tx_wptr_get());
        printf("  %-25s: %d\n", "PRL RX state", prl_rx_state_get());
        printf("  %-25s: %d\n", "PRL RX PKT", g_sys_pd_info.rx_pkt_cnt);
        printf("  %-25s: 0x%08X\n", "PRL RX DMA Addr", prl_msg_rx_dma_start_addr_get());
        printf("  %-25s: 0x%08X\n", "PRL RX Buf Addr", (u32_t)prl_msg_rx_head_get());
        printf("  %-25s: 0x%08X\n", "PRL RX RPTR", prl_msg_rx_rptr_get());
        printf("  %-25s: 0x%08X\n", "PRL RX WPTR", prl_msg_rx_wptr_get());
        printf("  %-25s: %d\n", "PRL HR state", prl_hr_state_get());
        printf("  %-25s: %d\n", "CC state", dpm_cc_state_get());
        printf("  %-25s: %d\n", "PE state", pe_state_get());
        printf("  %-25s: %s\n", "PRS IN Progress", g_cli_true_str[pe_prs_in_prog_get() ? TRUE : FALSE]);
        printf("  %-25s: %s\n", "Dead battery", g_cli_true_str[dpm_port_dead_battery_get()]);
#if SYS_QUICK_CHARGE_ENABLED
        printf("  %-25s: %d\n", "QC state", dpm_qc_state_get(&g_usbc_qc_info));
#endif
        printf("  %-25s: %u\n\n", "PD Hook Tick", g_sys_pd_info.continuous_timer_tick);
        printf("  %-25s: %s\n", "non_interruptible_AMS_entered", g_cli_true_str[pe_non_interruptible_AMS_entered_get() ? TRUE : FALSE]);
        printf("  %-25s: %s\n", "pe_interruptible_AMS_entered", g_cli_true_str[pe_interruptible_AMS_entered_get() ? TRUE : FALSE]);
        printf("  %-25s: %s\n", "PRS in PROG", g_cli_true_str[pe_prs_in_prog_get() ? TRUE : FALSE]);
        printf("  %-25s: %s\n", "Hard Reset in PROG", g_cli_true_str[pe_hard_reset_in_prog() ? TRUE : FALSE]);
        printf("  %-25s: %s\n\n", "TXERR", g_cli_true_str[(pe_prl_msg_txerr_get()) ? TRUE : FALSE]);
        printf("  %-25s: 0x%02X\n", "RX Filter Init Value", usbpd_cfg_port_init_cc_rx_filter_sel_get());
        printf("  %-25s: 0x%02X\n", "Half Bit Period Init Value", usbpd_cfg_port_init_cc_half_bit_get());
        printf("  %-25s: 0x%02X\n", "RX REF SEL Init Value", usbpd_cfg_port_init_cc_ref_sel_get());
        printf("  %-25s: 0x%02X\n", "CC ES Init Value", usbpd_cfg_port_init_cc_es_get());
        printf("  %-25s: 0x%02X\n", "CC Half Bit Period", usbpd_cfg_port_init_cc_half_bit_get());
        printf("  %-25s: 0x%02X\n", "LDO1 Init Value", usbpd_cfg_port_init_ldo1_get());
        printf("  %-25s: 0x%02X\n", "LDO2 Init Value", usbpd_cfg_port_init_ldo2_get());
        printf("  %-25s: 0x%02X\n", "LDO2 Runtime Value", usbpd_cfg_port_runtime_ldo2_get());
        printf("  %-25s: 0x%02X\n", "CC Freq Runtime Value", usbpd_cfg_port_runtime_cc_freq_get());
        printf("  %-25s: 0x%02X\n", "RD Runtime Value", usbpd_cfg_port_runtime_rd_get());
    }
    else if (0 == strcmp("cnt", argv[1]))
    {
        if (0 == strcmp("clear", argv[2]))
        {
            g_sys_pd_info.tx_pkt_cnt = 0;
            g_sys_pd_info.rx_pkt_cnt = 0;
        }
        else 
        {
	        printf(" Packet Counter: \n");
            printf("  %-25s: %u\n", "PRL TX PKT", g_sys_pd_info.tx_pkt_cnt);
            printf("  %-25s: %u\n", "PRL RX PKT", g_sys_pd_info.rx_pkt_cnt);
        }
    }
    else if (0 == strcmp("fst", argv[1]))
    {
        if (0 == strcmp("send", argv[2]))
        {
            DRV_REG_FIELD_SET(DPM_PRL_REG,FRS_ENA,0x01);
            DRV_REG_FIELD_SET(DPM_PRL_REG,FRS_TX_ENA,0x01);
            rtc_delay_us(90);
            DRV_REG_FIELD_SET(DPM_PRL_REG,FRS_TX_ENA,0x00);
            DRV_REG_FIELD_SET(DPM_PRL_REG,FRS_ENA,0x00);
        }
        else 
        {
	        printf(" cmd err \n");
        }
    }
#if SYS_FW_UPDATE_TEST_EN
    else if (0 == strcmp("fw", argv[1]))
    {
        if (0 == strcmp("update", argv[2]))
        {
            g_sys_pd_info.fw_update_en = true;
            sys_update_fw_process();
        }
        else 
        {
	        printf(" cmd err\n");
           
        }
    }
#endif
#if CLI_INCLUDE_PDCFG
    else if (0 == strcmp("test", argv[1])) 
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("on", argv[2]))
        {
            usbpd_cfg_test_mode_set(TRUE);
        }
        else if (0 == strcmp("off", argv[2]))
        {
            usbpd_cfg_test_mode_set(FALSE);
        }
        else 
        {
            return(CLI_CMD_NOT_FOUND);
        }
    }
    else if (0 == strcmp("ver", argv[1])) 
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("2", argv[2]))
        {
            usbpd_cfg_port_spec_rev_set(SPEC_REVISION_2_0);
        }
        else if (0 == strcmp("3", argv[2]))
        {
            usbpd_cfg_port_spec_rev_set(SPEC_REVISION_3_0);
        }
        else 
        {
            return(CLI_CMD_NOT_FOUND);
        }
    }
    else if (0 == strcmp("runtime", argv[1]))
    {
        if (0 == strcmp("ccfreq", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0xFF)
            {
                usbpd_cfg_port_runtime_cc_freq_set(tmp);
                usbpd_cfg_port_runtime_cc_freq_flg_set(TRUE);
            }
            else {
                usbpd_cfg_port_runtime_cc_freq_set(0);
                usbpd_cfg_port_runtime_cc_freq_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("ldo2", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x1F)
            {
                usbpd_cfg_port_runtime_ldo2_set(tmp);
                usbpd_cfg_port_runtime_ldo2_flg_set(TRUE);
            }
            else {
                usbpd_cfg_port_runtime_ldo2_set(0);
                usbpd_cfg_port_runtime_ldo2_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("rd", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0xF)
            {
                usbpd_cfg_port_runtime_rd_set(tmp);
                usbpd_cfg_port_runtime_rd_flg_set(TRUE);
            }
            else {
                usbpd_cfg_port_runtime_rd_set(0);
                usbpd_cfg_port_runtime_rd_flg_set(FALSE);
            }
        }
    }
    else if (0 == strcmp("init", argv[1]))
    {
        if (0 == strcmp("halfbit", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            DRV_REG_FIELD_SET(DPM_REG_1, HALF_BIT_SEL, tmp);
            if (tmp <= 0x7)
            {
                usbpd_cfg_port_init_cc_half_bit_set(tmp);
                usbpd_cfg_port_init_cc_half_bit_flg_set(TRUE);
                DRV_REG_FIELD_SET(DPM_REG_1, HALF_BIT_SEL, usbpd_cfg_port_init_cc_half_bit_get());
            }
            else {
                usbpd_cfg_port_init_cc_half_bit_set(0);
                usbpd_cfg_port_init_cc_half_bit_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("ldo1", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x1F)
            {
                usbpd_cfg_port_init_ldo1_set(tmp);
                usbpd_cfg_port_init_ldo1_flg_set(TRUE);
                DRV_REG_FIELD_SET(ANA_TRIM_REG,TUNE33,usbpd_cfg_port_init_ldo1_get());
            }
            else {
                usbpd_cfg_port_init_ldo1_set(0);
                usbpd_cfg_port_init_ldo1_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("ldo2", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x1F)
            {
                usbpd_cfg_port_init_ldo2_set(tmp);
                usbpd_cfg_port_init_ldo2_flg_set(TRUE);
                DRV_REG_FIELD_SET(ANA_TRIM_REG,TURNBG,usbpd_cfg_port_init_ldo2_get());
            }
            else {
                usbpd_cfg_port_init_ldo2_set(0);
                usbpd_cfg_port_init_ldo2_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("cces", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x7)
            {
                usbpd_cfg_port_init_cc_es_set(tmp);
                usbpd_cfg_port_init_cc_es_flg_set(TRUE);
                DRV_REG_FIELD_SET(CC_IO_CFG_REG, CC1_ES, usbpd_cfg_port_init_cc_es_get());
                DRV_REG_FIELD_SET(CC_IO_CFG_REG, CC2_ES, usbpd_cfg_port_init_cc_es_get());
            }
            else {
                usbpd_cfg_port_init_cc_es_set(0);
                usbpd_cfg_port_init_cc_es_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("rxfilter", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x3)
            {
                usbpd_cfg_port_init_cc_rx_filter_sel_set(tmp);
                usbpd_cfg_port_init_cc_rx_filter_sel_flg_set(TRUE);
                DRV_REG_FIELD_SET(DPM_REG_1, RX_FILTER_SEL, usbpd_cfg_port_init_cc_rx_filter_sel_get());
            }
            else {
                usbpd_cfg_port_init_cc_rx_filter_sel_set(0);
                usbpd_cfg_port_init_cc_rx_filter_sel_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("stc", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x7)
            {
                usbpd_cfg_port_init_adc_stc_set(tmp);
                usbpd_cfg_port_init_adc_stc_flg_set(TRUE);
                drv_adc_stc_set(usbpd_cfg_port_init_adc_stc_get());
            }
            else {
                usbpd_cfg_port_init_adc_stc_set(0);
                usbpd_cfg_port_init_adc_stc_flg_set(FALSE);
            }
        }
        else if (0 == strcmp("ccref", argv[2]))
        {
            tmp = strtoul(argv[3], (char **)0, 0);
            if (tmp <= 0x3)
            {
                usbpd_cfg_port_init_cc_ref_sel_set(tmp);
                usbpd_cfg_port_init_cc_ref_sel_flg_set(TRUE);
                drv_adc_stc_set(usbpd_cfg_port_init_cc_ref_sel_get());
            }
            else {
                usbpd_cfg_port_init_cc_ref_sel_set(0);
                usbpd_cfg_port_init_cc_ref_sel_flg_set(FALSE);
            }
        }
    }
    else if (0 == strcmp("retry", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        if (tmp <= 3)
        {
            usbpd_cfg_port_retry_cnt_set(tmp);
        }
        else {
            usbpd_cfg_port_retry_cnt_set(2);
        }
        DRV_REG_FIELD_SET(DPM_PRL_REG,RETRY_CNT,usbpd_cfg_port_retry_cnt_get());
    }
#if VENDOR_DEFINE_ENABLED
    else if (0 == strcmp("svid", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        usbpd_cfg_vd_usb_svid_set(tmp);
    }
    else if (0 == strcmp("vid", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        usbpd_cfg_vd_usb_vid_set(tmp);
    }
    else if (0 == strcmp("bcd", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        usbpd_cfg_vd_usb_bcd_device_set(tmp);
    }
    else if (0 == strcmp("pid", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        usbpd_cfg_vd_usb_prod_id_set(tmp);
    }
    else if (0 == strcmp("tid", argv[1]))
    {
        tmp = strtoul(argv[2], (char **)0, 0);
        usbpd_cfg_vd_usb_tid_set(tmp);
    }
#endif /* VENDOR_DEFINE_ENABLED */
    else if (0 == strcmp("mfr", argv[1]))
    {
        usbpd_cfg_mfr_info_set((const u8_t *)argv[2],strlen(argv[2]));
    }
#if SYS_SMG_DISPLAY_ENABLED
    else if (0 == strcmp("smg", argv[1]))
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("on", argv[2]))
        {
            sys_smg_ctrl_on_set(TRUE);
        }
        else if (0 == strcmp("off", argv[2]))
        {
        	sys_smg_ctrl_on_set(FALSE);
        }
        else 
        {
            sys_smg_display_data_set(strtoul(argv[2], (char **)0, 0));
        }
    }
#endif /* SYS_SMG_DISPLAY_ENABLED */
#if (SYS_OLED_DISPLAY_ENABLED)
    else if (0 == strcmp("oled", argv[1]))
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("on", argv[2]))
        {
            usbpd_cfg_oled_display_mode_set(TRUE);
            sys_oled_control(TRUE);
        }
        else if (0 == strcmp("off", argv[2]))
        {
        	usbpd_cfg_oled_display_mode_set(FALSE);
        	sys_oled_control(FALSE);
        }
        else 
        {
            return(CLI_CMD_NOT_FOUND);
        }
    }
#endif
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
    else if (0 == strcmp("capture", argv[1]))
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("on", argv[2]))
        {
            usbpd_cfg_capture_mode_set(TRUE);
            usbpd_cfg_port_def_pdr_set(PD_ROLE_CAPTURE);
            usbpd_cfg_prod_type_set(UPD_PRODUCT_UNDEF);
        }
        else if (0 == strcmp("off", argv[2]))
        {
            usbpd_cfg_capture_mode_set(FALSE);
            if (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get())
            {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER_CONSUMER);
            }
            else if (POWER_ROLE_SOURCE == usbpd_cfg_port_def_pr_get())
            {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER);
            }
            else {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_CONSUMER);
            }
            usbpd_cfg_prod_type_set(UPD_PRODUCT_PSD);
        }
        else
        {
            return(CLI_CMD_NOT_FOUND);
        }
        dpm_port_reset();
    }
#if CABLE_PLUG_ENABLED
    else if (0 == strcmp("cbl", argv[1])) 
    {
        if (argc < 3)
            return(CLI_CMD_PARAM_ERROR);

        if (0 == strcmp("on", argv[2]))
        {
            usbpd_cfg_cable_plug_set(TRUE);
            usbpd_cfg_port_def_pdr_set(PD_ROLE_CABLE_PLUG);
            usbpd_cfg_prod_type_set(UPD_CBL_PROD_PASSIVE_CBL);
            usbpd_cfg_port_vdm_vbus_thr_cbl_set(TRUE);
            usbpd_cfg_port_vdm_sstx1_dir_supp_set(TRUE);
            usbpd_cfg_port_vdm_sstx2_dir_supp_set(TRUE);
            usbpd_cfg_port_vdm_ssrx1_dir_supp_set(TRUE);
            usbpd_cfg_port_vdm_ssrx2_dir_supp_set(TRUE);
            usbpd_cfg_port_vdm_usb_ss_sig_supp_set(2);
            usbpd_cfg_port_vdm_cbl_term_type_set(1);
            usbpd_cfg_port_vdm_vbus_curr_cap_set(VBUS_CURR_HANDLING_CAP_3A);
        }
        else if (0 == strcmp("off", argv[2]))
        {
            usbpd_cfg_cable_plug_set(FALSE);
            if (POWER_ROLE_DRP == usbpd_cfg_port_def_pr_get(0))
            {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER_CONSUMER);
            }
            else if (POWER_ROLE_SOURCE == usbpd_cfg_port_def_pr_get(0)) 
            {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER);
            }
            else {
                usbpd_cfg_port_def_pdr_set(PD_ROLE_CONSUMER);
            }
            usbpd_cfg_prod_type_set(UPD_PRODUCT_PSD);
        }
        else 
        {
            return(CLI_CMD_NOT_FOUND);
        }
        dpm_port_reset();
    }
#endif
#endif /* (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE) */
#endif /* CLI_INCLUDE_PDCFG */
    else
    {
        tmp = strtoul(argv[2], (char **)0, 0);

        if (0 == strcmp("on", argv[1]))
        {
            usbpd_cfg_port_no_pd_mode_set(FALSE);
            dpm_port_reset();
        }
        else if (0 == strcmp("off", argv[1]))
        {
            usbpd_cfg_port_no_pd_mode_set(TRUE);
            dpm_port_reset();
        }
        else if (0 == strcmp("r2", argv[1]))
        {
            usbpd_cfg_port_spec_rev_set(SPEC_REVISION_2_0);
            dpm_port_reset();
        }
        else if (0 == strcmp("r3", argv[1]))
        {
            usbpd_cfg_port_spec_rev_set(SPEC_REVISION_3_0);
            dpm_port_reset();
        }
#if CLI_INCLUDE_PDCFG
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
        else if (0 == strcmp("pr", argv[1])) 
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (0 == strcmp("drp", argv[2]))
            {
                usbpd_cfg_port_def_pr_set(POWER_ROLE_DRP);
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER_CONSUMER);
                usbpd_cfg_port_dual_role_pwr_set(TRUE);
            }
            else if (0 == strcmp("src", argv[2]))
            {
                usbpd_cfg_port_def_pr_set(POWER_ROLE_SOURCE);
                usbpd_cfg_port_def_pdr_set(PD_ROLE_PROVIDER);
                usbpd_cfg_port_dual_role_pwr_set(FALSE);
            }
            else if (0 == strcmp("snk", argv[2]))
            {
                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(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
            dpm_port_reset();
        }
#endif /* (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE) */
        else if (0 == strcmp("dr", argv[1])) 
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (0 == strcmp("drd", argv[2]))
            {
                usbpd_cfg_port_def_dr_set(USB_DATA_ROLE_DRD);
                usbpd_cfg_port_drs_cap_set(TRUE);
            }
            else if (0 == strcmp("dfp", argv[2]))
            {
                usbpd_cfg_port_def_dr_set(USB_DATA_ROLE_DFP);
                usbpd_cfg_port_drs_cap_set(FALSE);
            }
            else if (0 == strcmp("ufp", argv[2]))
            {
                usbpd_cfg_port_def_dr_set(USB_DATA_ROLE_UFP);
                usbpd_cfg_port_drs_cap_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
            dpm_port_reset();
        }
        else if (0 == strcmp("cs", argv[1])) 
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get()))
                return(CLI_CMD_DENIED);

            if (0 == strcmp("80", argv[2]))
            {
                usbpd_cfg_port_current_src_supply_type_set(CURRENT_SRC_SUPPLY_80uA);
                usbpd_cfg_port_vrd_min_src_set(VRD_MIN_SRC_DEF_USB);
                usbpd_cfg_port_vrd_max_src_set(VRD_MAX_SRC_DEF_USB);
                usbpd_cfg_port_vra_min_set(VRA_MIN_DEF_USB);
                usbpd_cfg_port_vra_max_set(VRA_MAX_DEF_USB);
                usbpd_cfg_port_vopen_set(VOPEN_DEF_USB);
            }
            else if (0 == strcmp("180", argv[2]))
            {
                usbpd_cfg_port_current_src_supply_type_set(CURRENT_SRC_SUPPLY_180uA);
                usbpd_cfg_port_vrd_min_src_set(VRD_MIN_SRC_5V_1P5A);
                usbpd_cfg_port_vrd_max_src_set(VRD_MAX_SRC_5V_1P5A);
                usbpd_cfg_port_vra_min_set(VRA_MIN_5V_1P5A);
                usbpd_cfg_port_vra_max_set(VRA_MAX_5V_1P5A);
                usbpd_cfg_port_vopen_set(VOPEN_5V_1P5A);
            }
            else if (0 == strcmp("330", argv[2]))
            {
                usbpd_cfg_port_current_src_supply_type_set(CURRENT_SRC_SUPPLY_330uA);
                usbpd_cfg_port_vrd_min_src_set(VRD_MIN_SRC_5V_3A);
                usbpd_cfg_port_vrd_max_src_set(VRD_MAX_SRC_5V_3A);
                usbpd_cfg_port_vra_min_set(VRA_MIN_5V_3A);
                usbpd_cfg_port_vra_max_set(VRA_MAX_5V_3A);
                usbpd_cfg_port_vopen_set(VOPEN_5V_3A);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#if (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE)
        else if (0 == strcmp("trysrc", argv[1])) 
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_DRP != usbpd_cfg_port_def_pr_get()))
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_try_src_set(TRUE);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_try_src_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* (DPM_POWER_ROLE_DRP==DPM_POWER_ROLE) */
#if 1
        else if (0 == strcmp("vrdmin-src", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }
            else {
                usbpd_cfg_port_vrd_min_src_set(tmp);
            }
        }
        else if (0 == strcmp("vrdmax-src", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }
            else {
                usbpd_cfg_port_vrd_max_src_set(tmp);
            }
        }
        else if (0 == strcmp("vrdmin-snk", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (POWER_ROLE_SOURCE != usbpd_cfg_port_def_pr_get())
            {
                usbpd_cfg_port_vrd_min_snk_set(tmp);
            }
            else {
                return(CLI_CMD_DENIED);
            }
        }
        else if (0 == strcmp("vrdmax-snk", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (POWER_ROLE_SOURCE != usbpd_cfg_port_def_pr_get())
            {
                usbpd_cfg_port_vrd_max_snk_set(tmp);
            }
            else {
                return(CLI_CMD_DENIED);
            }
        }
        else if (0 == strcmp("vramin", argv[1]))
        {
            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }

            usbpd_cfg_port_vra_min_set(tmp);
        }
        else if (0 == strcmp("vramax", argv[1]))
        {
            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }

            usbpd_cfg_port_vra_max_set(tmp);
        }
        else if (0 == strcmp("vopen", argv[1]))
        {
            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }

            usbpd_cfg_port_vopen_set(tmp);
        }
#endif /* #if 1 */
#if SYS_QUICK_CHARGE_ENABLED
        else if (0 == strcmp("qc", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("v2", argv[2]))
            {
                sys_qc_init();
                usbpd_cfg_port_quick_charge_en_set(TRUE);
                usbpd_cfg_port_quick_charge_ver_set(DPM_QC_V2);
            }
            else if (0 == strcmp("v3", argv[2]))
            {
                sys_qc_init();
                usbpd_cfg_port_quick_charge_en_set(TRUE);
                usbpd_cfg_port_quick_charge_ver_set(DPM_QC_V3);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_quick_charge_en_set(FALSE);
                sys_qc_disable();
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* SYS_QUICK_CHARGE_ENABLED */
        else if (0 == strcmp("vbus-check", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vbus_check_set(TRUE);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vbus_check_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
        else if (0 == strcmp("vconn", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vconn_en_set(TRUE);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vconn_en_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
        else if (0 == strcmp("power-limit", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get()))
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_power_limited_set(TRUE);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_power_limited_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#if SYS_PWM_CTRL_VOLT_ENABLED
        else if (0 == strcmp("pwm", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get()))
            {
                return(CLI_CMD_DENIED);
            }

            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_src_pwm_en_set(TRUE);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_src_pwm_en_set(FALSE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
        else if (0 == strcmp("pwm-per", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get()))
            {
                return(CLI_CMD_DENIED);
            }

            usbpd_cfg_port_src_pwm_per_set(tmp);
        }
        else if (0 == strcmp("pwm-fixed", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get() || 
                (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get()))
            {
                return(CLI_CMD_DENIED);
            }

            if (argc < 4)
                return(CLI_CMD_PARAM_ERROR);

            tmp = strtoul(argv[3], (char **)0, 0);

            if (0 == strcmp("5v", argv[2]))
            {
                usbpd_cfg_port_src_fixed_pwr_pwm_duty_set(sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_5V), tmp);
            }
            else if (0 == strcmp("9v", argv[2]))
            {
                if (CFG_VOLTAGE_5V_IDX == sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_9V))
                {
                    return(CLI_CMD_DENIED);
                }
                usbpd_cfg_port_src_fixed_pwr_pwm_duty_set(sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_9V), tmp);
            }
            else if (0 == strcmp("12v", argv[2]))
            {
                if (CFG_VOLTAGE_5V_IDX == sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_12V))
                {
                    return(CLI_CMD_DENIED);
                }
                usbpd_cfg_port_src_fixed_pwr_pwm_duty_set(sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_12V), tmp);
            }
            else if (0 == strcmp("15v", argv[2]))
            {
                if (CFG_VOLTAGE_5V_IDX == sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_15V))
                {
                    return(CLI_CMD_DENIED);
                }
                usbpd_cfg_port_src_fixed_pwr_pwm_duty_set(sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_15V), tmp);
            }
            else if (0 == strcmp("20v", argv[2]))
            {
                if (CFG_VOLTAGE_5V_IDX == sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_20V))
                {
                    return(CLI_CMD_DENIED);
                }
                usbpd_cfg_port_src_fixed_pwr_pwm_duty_set(sys_pd_cfg_src_fixed_power_profile_index_get(VOLTAGE_20V), tmp);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* SYS_PWM_CTRL_VOLT_ENABLED */
        else if (0 == strcmp("profile", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            if (POWER_ROLE_SINK == usbpd_cfg_port_def_pr_get())
            {
                return(CLI_CMD_DENIED);
            }

            if ((POWER_PROFILE_RESV < tmp) && (tmp < POWER_PROFILE_MAX))
            {
                sys_pd_cfg_src_power_profile_set(tmp);
            }
            else 
            {
                return(CLI_CMD_PARAM_ERROR);
            }
        }
        else if (0 == strcmp("opr-pwr", argv[1]))
        {
            if (usbpd_cfg_cable_plug_get() || (POWER_ROLE_SOURCE == usbpd_cfg_port_def_pr_get()))
                return(CLI_CMD_DENIED);

            if ((SNK_POWER_REQUIRE_15W <= tmp) && (tmp < SNK_POWER_REQUIRE_MAX))
            {
                sys_pd_cfg_snk_operating_power_profile_set(tmp);
            }
            else 
            {
                return(CLI_CMD_PARAM_ERROR);
            }
        }
#if VENDOR_DEFINE_ENABLED
        else if (0 == strcmp("vdm", argv[1]))
        {
            if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vdm_en_set(FALSE);
            }
            else if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vdm_en_set(TRUE);
            }
        }
        else if (0 == strcmp("vdm-startup", argv[1]))
        {
            if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vdm_src_startup_en_set(FALSE);
            }
            else if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vdm_src_startup_en_set(TRUE);
            }
        }
#if VENDOR_DEFINE_MODE_ENABLED
        else if (0 == strcmp("vdm-mode", argv[1]))
        {
            if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vdm_modal_opr_supp_set(FALSE);
            }
            else if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vdm_modal_opr_supp_set(TRUE);
            }
        }
#endif /* VENDOR_DEFINE_MODE_ENABLED */
#if CABLE_PLUG_ENABLED
        else if (0 == strcmp("sop2", argv[1]))
        {
            if (argc < 3)
                return(CLI_CMD_PARAM_ERROR);
            if (!usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);
            if (0 == strcmp("on", argv[2]))
            {
                usbpd_cfg_port_vdm_sop2_ctrler_pres_set(TRUE);
                usbpd_cfg_prod_type_set(UPD_CBL_PROD_ACTIVE_CBL);
                usbpd_cfg_port_vdm_cbl_term_type_set(3);
            }
            else if (0 == strcmp("off", argv[2]))
            {
                usbpd_cfg_port_vdm_sop2_ctrler_pres_set(FALSE);
                usbpd_cfg_prod_type_set(UPD_CBL_PROD_PASSIVE_CBL);
                usbpd_cfg_port_vdm_cbl_term_type_set(1);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
        else if (0 == strcmp("vcc", argv[1]))
        {
            if (argc < 4)
                return(CLI_CMD_PARAM_ERROR);
            if (0 == strcasecmp("3a", argv[2]))
            {
                usbpd_cfg_port_vdm_vbus_curr_cap_set(VBUS_CURR_HANDLING_CAP_3A);
            }
            else if (0 == strcasecmp("5a", argv[2]))
            {
                usbpd_cfg_port_vdm_vbus_curr_cap_set(VBUS_CURR_HANDLING_CAP_5A);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* CABLE_PLUG_ENABLED */
        else if (0 == strcmp("ss", argv[1]))
        {
            if (argc < 4)
                return(CLI_CMD_PARAM_ERROR);
            if (0 == strcasecmp("v2", argv[2]))
            {
                usbpd_cfg_port_vdm_usb_ss_sig_supp_set(0);
            }
            else if (0 == strcasecmp("v3g1", argv[2]))
            {
                usbpd_cfg_port_vdm_usb_ss_sig_supp_set(1);
            }
            else if (0 == strcasecmp("v3a", argv[2]))
            {
                usbpd_cfg_port_vdm_usb_ss_sig_supp_set(2);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* VENDOR_DEFINE_ENABLED */
#endif /* CLI_INCLUDE_PDCFG */
        else if (0 == strcmp(argv[1], "bist-cm2"))
        {
            tmp = str_to_sop_type(argv[2]);
            dpm_bist_carrier_mode2_req(tmp);
        }
        else if (0 == strcmp(argv[1], "bist-data"))
        {
            if (argc < 4)
                return(CLI_CMD_PARAM_ERROR);

            u8_t bist_data[DPM_BIST_TEST_DATA_SIZE];
            int len = (int)strtoul(argv[2], (char **)0, 0);

            if (len > DPM_BIST_TEST_DATA_SIZE)
                return(CLI_CMD_PARAM_ERROR);

            if (len)
            {
                strtohex(bist_data, argv[3], len);
            }

            tmp = str_to_sop_type(argv[4]);
            dpm_bist_test_data_req(bist_data, len, tmp);
        }
#if CLI_INCLUDE_PRS
        else if (0 == strcmp(argv[1], "prs"))
        {
            if ((POWER_ROLE_DRP != usbpd_cfg_port_def_pr_get()) || usbpd_cfg_cable_plug_get())
            {
                return(CLI_CMD_DENIED);
            }

            dpm_pr_swp_req_set(TRUE);
        }
#endif /* CLI_INCLUDE_PRS */
#if CLI_INCLUDE_DRS
        else if (0 == strcmp(argv[1], "drs"))
        {
            if (!usbpd_cfg_port_drs_cap_get() || usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            dpm_dr_swp_req_set(TRUE);
        }
#endif /* CLI_INCLUDE_DRS */
#if CLI_INCLUDE_VCS
        else if (0 == strcmp(argv[1], "vcs"))
        {
            if (usbpd_cfg_cable_plug_get())
                return(CLI_CMD_DENIED);

            dpm_vconn_swp_req_set(TRUE);
        }
#endif /* CLI_INCLUDE_VCS */
#if CLI_INCLUDE_GETSRC
        else if (0 == strcmp(argv[1], "getsrc"))
        {
            if (POWER_MODE_SOURCE == dpm_current_pwr_mode_get())
            {
                dpm_get_src_cap_req_set(TRUE);
            }
            else {
                dpm_req_src_cap_update_set(TRUE);
            }
        }
#endif /* CLI_INCLUDE_GETSRC */
#if CLI_INCLUDE_GETSNK
        else if (0 == strcmp(argv[1], "getsnk"))
        {
            dpm_get_snk_cap_req_set(TRUE);
        }
#endif /* CLI_INCLUDE_GETSNK */
#if CLI_INCLUDE_GOTOMIN
        else if (0 == strcmp(argv[1], "gotomin"))
        {
            dpm_goto_min_req_set(TRUE);
        }
#endif /* CLI_INCLUDE_GOTOMIN */
#if CLI_INCLUDE_NEWPWR
        else if (0 == strcmp(argv[1], "newpwr"))
        {
            if (!dpm_new_power_level_req())
            {
                return(CLI_CMD_FAILURE);
            }
        }
#endif /* CLI_INCLUDE_NEWPWR */
#if CLI_INCLUDE_HRST
        else if (0 == strcmp(argv[1], "hrst"))
        {
            if (pe_pd_connected_get())
            {
                dpm_hard_reset_req_set(TRUE);
            }
            else {
                DRV_REG_FIELD_SET(DPM_PRL_REG,HRST_REQ_FRM_PLCENG,TRUE);
            }
        }
#endif /* CLI_INCLUDE_HRST */
#if CLI_INCLUDE_CBL_RST
        else if (0 == strcmp(argv[1], "crst"))
        {
#if 0  /* modified by James Gan - 2019-06-05 */
            if (pe_pd_connected_get())
            {
                dpm_cable_reset_req_set(TRUE);
            }
            else {
                DRV_REG_FIELD_SET(DPM_PRL_REG,CBL_RST_REQ_FRM_PLCENG,TRUE);
            }
#else
            DRV_REG_FIELD_SET(DPM_PRL_REG,CBL_RST_REQ_FRM_PLCENG,TRUE);
#endif /* #if 0 */
        }
#endif /* CLI_INCLUDE_CBL_RST */
#if CLI_INCLUDE_SRST
        else if (0 == strcmp(argv[1], "srst"))
        {
            if (dpm_current_pwr_mode_get())
            {
                pe_src_send_soft_reset();
            }
            else {
                pe_snk_send_soft_reset();
            }
        }
#endif /* CLI_INCLUDE_SRST */
#if CLI_INCLUDE_EXT
        else if (0 == strcmp(argv[1], "alert"))
        {
            dpm_alert_type_set(tmp);
            dpm_alert_req_set(TRUE);
        }
        else if (0 == strcmp(argv[1], "get"))
        {
            if (argc < 3)
                return(CLI_CMD_PARAM_ERROR);
            if (0 == strcmp("status", argv[2]))
            {
                dpm_get_ext_status_req_set(TRUE);
            }
            else if (0 == strcmp("batsta", argv[2]))
            {
                dpm_get_ext_bat_status_req_set(TRUE);
            }
            else if (0 == strcmp("batcap", argv[2]))
            {
                dpm_get_ext_bat_cap_req_set(TRUE);
            }
            else if (0 == strcmp("extsrc", argv[2]))
            {
                dpm_get_ext_src_cap_req_set(TRUE);
            }
            else if (0 == strcmp("extsnk", argv[2]))
            {
                dpm_get_ext_snk_cap_req_set(TRUE);
            }
            else if (0 == strcmp("mfr", argv[2]))
            {
                dpm_get_ext_mfr_req_set(TRUE);
            }
            else if (0 == strcmp("pps", argv[2]))
            {
                dpm_get_ext_pps_status_req_set(TRUE);
            }
            else if (0 == strcmp("ctry-codes", argv[2]))
            {
                dpm_get_ext_ctry_codes_req_set(TRUE);
            }
            else if (0 == strcmp("ctry-info", argv[2]))
            {
                dpm_get_ext_ctry_info_req_set(TRUE);
            }
            else 
            {
                return(CLI_CMD_NOT_FOUND);
            }
        }
#endif /* CLI_INCLUDE_EXT */

#if CLI_INCLUDE_MSG
        else if (0 == strcmp(argv[1], "msg"))
        {
            if (argc < 5)
                return(CLI_CMD_PARAM_ERROR);

            if (dpm_tx_in_prog_get())
            {
                drv_uart_puts("Message is being sent, please wait a moment");
                return(CLI_CMD_FAILURE);
            }

            // parsing sop type
            tmp = strtoul(argv[2], &p, 0);
            if ((tmp > 4) || ((p != NULL) && (*p != '\0')))
                return(CLI_CMD_PARAM_ERROR);

            int act = strtoul(argv[4], &p, 0);
            if ((act > 8) || ((p != NULL) && (*p != '\0') && (0 != strcmp(argv[4], "x"))))
                return(CLI_CMD_PARAM_ERROR);

            if ((act == 0) && (0 != strcmp(argv[4], "x")))
            {
                cli_msg_tx_len = 0;
            }
            cli_msg_tx_len += strtohex((u8_t *)&tx_data[cli_msg_tx_len], argv[3], UPD20_BUF_LEN-cli_msg_tx_len);
            if (0 == strcmp(argv[4], "x"))
            {
                sync_enter_critical();
                prl_msg_tx_desc_t tx_desc;
                tx_desc.u.u32 = 0;
                tx_desc.u.desc.sop = tmp;
                tx_desc.u.desc.len = cli_msg_tx_len;
                tx_desc.u.desc.num = 1;
                prl_msg_tx_desc_set(tx_desc.u.u32);
                sync_exit_critical();
                drv_uart_puts(" TX Message:");
                drv_uart_puthex((u8_t *)&tx_data[0], cli_msg_tx_len, FALSE);
                cli_msg_tx_len = 0;
            }
        }
#endif /* CLI_INCLUDE_MSG */
#if VENDOR_DEFINE_ENABLED
        else if (0 == strcmp(argv[1], "vdmtx"))
        {
            if (argc < 3)
                return(CLI_CMD_PARAM_ERROR);

            tmp = strtoul(argv[2], &p, 0);
            if ((p != NULL) && (*p != '\0'))
                return(CLI_CMD_PARAM_ERROR);

#if 0  /* deleted by James Gan - 2018-09-04 */
            if (((((0 <= tmp) && (tmp <= 2)) || ((10 <= tmp) && (tmp <= 11))) && dpm_ufp_mode_get()) ||
                ((3 <= tmp) && (tmp <= 5) && (dpm_ufp_mode_get() || !dpm_cbl_plug_detected_get())) || 
                ((7 <= tmp) && (tmp <= 9) && (dpm_ufp_mode_get() || !dpm_cbl_plug_detected_get() || !dpm_vdm_sop2_present_get())) || 
                ((6 == tmp) && (dpm_dfp_mode_get() && !usbpd_cfg_cable_plug_get())))
            {
                return(CLI_CMD_DENIED);
            }
#endif /* #if 0 */

            switch (tmp)
            {
            case 0: 
                pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOP);
                break;
            case 1:
                pe_txmsg_req_ex(VDM_DISC_SVID_CMD_MSG, MSG_SOP_TYPE_SOP);
                break;
            case 2: 
                pe_txmsg_req_ex(VDM_EXIT_MODE_CMD_MSG, MSG_SOP_TYPE_SOP);
                break;
            case 3:
                pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOPP);
                break;
            case 4: 
                pe_txmsg_req_ex(VDM_DISC_SVID_CMD_MSG, MSG_SOP_TYPE_SOPP);
                break;
            case 5:
                pe_txmsg_req_ex(VDM_EXIT_MODE_CMD_MSG, MSG_SOP_TYPE_SOPP);
                break;
            case 6:
                pe_txmsg_req_ex(VDM_ATTENTION_CMD_MSG, MSG_SOP_TYPE_SOP);
                break;
            case 7:
                pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOPPP);
                break;
            case 8: 
                pe_txmsg_req_ex(VDM_DISC_SVID_CMD_MSG, MSG_SOP_TYPE_SOPPP);
                break;
            case 9:
                pe_txmsg_req_ex(VDM_EXIT_MODE_CMD_MSG, MSG_SOP_TYPE_SOPPP);
                break;
            case 10:
                pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOPP_DBG);
                break;
            case 11:
                pe_txmsg_req_ex(VDM_DISC_IDENT_CMD_MSG, MSG_SOP_TYPE_SOPPP_DBG);
                break;
            default: 
                return(CLI_CMD_FAILURE);
            }
        }
#endif /* VENDOR_DEFINE_ENABLED */
        else {
            return(CLI_CMD_NOT_FOUND);
        }
    }

    return(CLI_CMD_SUCCESS);
}


void cli_cmd_usbpd_init()
{
    cli_cmd_list_add( "pd", g_cli_cmd_usbpd_help, cli_cmd_usbpd );
}

#endif
#endif

