/**
 * \file    pe_state.h
 * \brief   Policy engine state machine
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-05
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-05  Original Creation
 * 
 */
 
#ifndef __PE_STATE_H_
#define __PE_STATE_H_


#include "libc.h"
#include "drivers.h"
#include "usbpd.h"


#pragma pack(1)

#define N_RETRY_COUNT        3
#define N_HARD_RESET_CNT     2
#define N_CAPS_COUNT         50
#define N_DISC_IDENT_COUNT   20

/** \name  Policy Engine State definitions
 * \{ 
 */
typedef enum PE_STATE_DEF_e
{
    PE_IDLE,

    PE_SRC_STARTUP,
    PE_SRC_SEND_CAPABILITY,
    PE_SRC_NEGO_CAPABILITY,
    PE_SRC_TRANSIT_SUPPLY,
    PE_SRC_READY,
    PE_SRC_GIVE_SRC_CAP,
    PE_SRC_GET_SNK_CAP,
    PE_SRC_CAP_RESPONSE,
    PE_SRC_HARD_RESET,
    PE_SRC_HARD_RESET_RECEIVED,
    PE_SRC_TRANSIT_TO_DEFAULT,
    PE_SRC_DISCOVERY,
    PE_SRC_DISABLED,
    PE_SRC_SEND_SOFT_RESET,
    PE_SRC_SOFT_RESET,

    PE_SNK_STARTUP,
    PE_SNK_DISCOVERY,
    PE_SNK_WAIT_FOR_CAP,
    PE_SNK_EVALUATE_CAP,
    PE_SNK_SELECT_CAP,
    PE_SNK_TRANSIT_SNK,
    PE_SNK_READY,
    PE_SNK_GIVE_SNK_CAP,
    PE_SNK_GET_SRC_CAP,
    PE_SNK_HARD_RESET,
    PE_SNK_TRANSIT_TO_DEFAULT,
    PE_SNK_SEND_SOFT_RESET,
    PE_SNK_SOFT_RESET,

	// Dual Role state machine
    // Data Role Swap state machine
    PE_DRS_DFP_UFP_EVALUATE_DR_SWP,
    PE_DRS_DFP_UFP_ACCEPT_DR_SWP,
    PE_DRS_DFP_UFP_CHANGE_TO_UFP,
    PE_DRS_DFP_UFP_REJECT_DR_SWP,
    PE_DRS_DFP_UFP_SEND_DR_SWP,
    PE_DRS_UFP_DFP_EVALUATE_DR_SWP,
    PE_DRS_UFP_DFP_ACCEPT_DR_SWP,
    PE_DRS_UFP_DFP_CHANGE_TO_DFP,
    PE_DRS_UFP_DFP_REJECT_DR_SWP,
    PE_DRS_UFP_DFP_SEND_DR_SWP,

    // Power Role Swap state machine
    PE_PRS_SRC_SNK_EVALUATE_SWP,
    PE_PRS_SRC_SNK_ACCEPT_SWP,
    PE_PRS_SRC_SNK_TRANSIT_TO_OFF,
    PE_PRS_SRC_SNK_WAIT_SRC_ON,
    PE_PRS_SRC_SNK_REJECT_SWP,
    PE_PRS_SRC_SNK_SEND_SWP,
    PE_PRS_SRC_SNK_ASSERT_RD,
    PE_PRS_SNK_SRC_EVALUATE_SWP,
    PE_PRS_SNK_SRC_ACCEPT_SWP,
    PE_PRS_SNK_SRC_TRANSIT_TO_OFF,
    PE_PRS_SNK_SRC_SOURCE_ON,
    PE_PRS_SNK_SRC_REJECT_SWP,
    PE_PRS_SNK_SRC_SEND_SWP,
    PE_PRS_SNK_SRC_ASSERT_RP,
    PE_DR_SRC_GET_SRC_CAP,
    PE_DR_SRC_GIVE_SNK_CAP,
    PE_DR_SNK_GET_SNK_CAP,
    PE_DR_SNK_GIVE_SRC_CAP,

    // VCONN State machine
    PE_VCS_SEND_SWP,
    PE_VCS_EVALUATE_SWP,
    PE_VCS_REJECT_SWP,
    PE_VCS_ACCEPT_SWP,
    PE_VCS_WAIT_FOR_VCONN,
    PE_VCS_TURN_OFF_VCONN,
    PE_VCS_TURN_ON_VCONN,
    PE_VCS_SEND_PS_RDY,

    // Structured VDM State machine
    PE_UFP_VDM_GET_IDENTITY,
    PE_UFP_VDM_GET_IDENTITY_NAK,
    PE_UFP_VDM_SEND_IDENTITY,
    PE_UFP_VDM_GET_SVID,
    PE_UFP_VDM_GET_SVID_NAK,
    PE_UFP_VDM_SEND_SVID,
    PE_UFP_VDM_GET_MODE,
    PE_UFP_VDM_GET_MODE_NAK,
    PE_UFP_VDM_SEND_MODE,
    PE_UFP_VDM_EVALUATE_MODE_ENTRY,
    PE_UFP_VDM_MODE_ENTRY_ACK,
    PE_UFP_VDM_MODE_ENTRY_NAK,
    PE_UFP_VDM_MODE_EXIT,
    PE_UFP_VDM_MODE_EXIT_ACK,
    PE_UFP_VDM_MODE_EXIT_NAK,
    PE_UFP_VDM_ATTENTION_REQ,
    PE_DFP_UFP_VDM_IDENTITY_REQ,
    PE_DFP_UFP_VDM_IDENTITY_ACK,
    PE_DFP_UFP_VDM_IDENTITY_NAK,
    PE_DFP_CBL_VDM_IDENTITY_REQ,
    PE_DFP_CBL_VDM_IDENTITY_ACK,
    PE_DFP_CBL_VDM_IDENTITY_NAK,
    PE_DFP_VDM_SVID_REQ,
    PE_DFP_VDM_SVID_ACK,
    PE_DFP_VDM_SVID_NAK,
    PE_DFP_VDM_MODE_REQ,
    PE_DFP_VDM_MODE_ACK,
    PE_DFP_VDM_MODE_NAK,
    PE_DFP_VDM_MODE_ENTRY_REQ,
    PE_DFP_VDM_MODE_ENTRY_ACK,
    PE_DFP_VDM_MODE_ENTRY_NAK,
    PE_DFP_VDM_MODE_EXIT_REQ,
    PE_DFP_VDM_MODE_EXIT_ACK,
    PE_DFP_VDM_ATTENTION_REQ,
    PE_DFP_CBL_SEND_SOFT_RESET,
    PE_DFP_CBL_SEND_CABLE_RESET,
    PE_UFP_CBL_SEND_SOFT_RESET,
    PE_SRC_VDM_IDENTITY_REQ,
    PE_SRC_VDM_IDENTITY_ACK,
    PE_SRC_VDM_IDENTITY_NAK,

    // BIST State machine,
    PE_BIST_CARRIER_MODE2,

    // PD 3.0 state machine
    PE_Send_Not_Supported,
    PE_Not_Supported_Received,
    PE_Chunk_Received,
    PE_SRC_Ping,
    PE_Send_Alert,
    PE_Alert_Received,
    PE_SNK_Get_Source_Cap_Ext,
    PE_SRC_Give_Source_Cap_Ext,
    PE_SRC_Get_Sink_Cap_Ext,
    PE_SNK_Give_Sink_Cap_Ext,
    PE_Get_Status,
    PE_Give_Status,
    PE_SNK_Get_PPS_Status,
    PE_SRC_Give_PPS_Status,
    PE_Get_Battery_Cap,
    PE_Give_Battery_Cap,
    PE_Get_Battery_Status,
    PE_Give_Battery_Status,
    PE_Get_Manufacturer_Info,
    PE_Give_Manufacturer_Info,
    PE_Get_Country_Codes,
    PE_Give_Country_Codes,
    PE_Get_Country_Info,
    PE_Give_Country_Info,
    PE_Send_Security_Request,
    PE_Send_Security_Response,
    PE_Security_Response_Received,
    PE_Send_Firmware_Update_Request,
    PE_Send_Firmware_Update_Response,
    PE_Firmware_Update_Response_Received,
    PE_FRS_SRC_SNK_Evaluate_Swap,
    PE_FRS_SRC_SNK_Accept_Swap,
    PE_FRS_SRC_SNK_Transition_to_off,
    PE_FRS_SRC_SNK_Assert_Rd,
    PE_FRS_SRC_SNK_Wait_Source_on,
    PE_FRS_SNK_SRC_Start_AMS,
    PE_FRS_SNK_SRC_Send_Swap,
    PE_FRS_SNK_SRC_Transition_to_off,
    PE_FRS_SNK_SRC_Vbus_Applied,
    PE_FRS_SNK_SRC_Assert_Rp,
    PE_FRS_SNK_SRC_Source_on,
    PE_DR_SRC_Get_Source_Cap_Ext,
    PE_DR_SNK_Give_Source_Cap_Ext,
    PE_DR_SNK_Get_Sink_Cap_Ext,
    PE_DR_SRC_Give_Sink_Cap_Ext,

    PE_DISABLED_VDM_GOT_REQ,
    PE_DISABLED_VDM_SEND_RESP,

    PE_STATE_END
} PE_STATE_DEF_t;
/** \}*/

/** \name  USB to USB Cable State machine
 * \{ 
 */
typedef enum PE_CBL_STATE_DEF_e
{
    PE_CBL_READY,
    PE_CBL_GET_IDENTITY,
    PE_CBL_GET_IDENTITY_NAK,
    PE_CBL_SEND_IDENTITY,
    PE_CBL_GET_SVID,
    PE_CBL_GET_SVID_NAK,
    PE_CBL_SEND_SVID,
    PE_CBL_GET_MODE,
    PE_CBL_GET_MODE_NAK,
    PE_CBL_SEND_MODE,
    PE_CBL_EVALUATE_MODE_ENTRY,
    PE_CBL_MODE_ENTRY_ACK,
    PE_CBL_MODE_ENTRY_NAK,
    PE_CBL_MODE_EXIT,
    PE_CBL_MODE_EXIT_ACK,
    PE_CBL_MODE_EXIT_NAK,
    PE_CBL_SOFT_RESET,
    PE_CBL_HARD_RESET,
    PE_CBL_BIST_CARRIER_MODE2,
	PE_CBL_STATE_END
} PE_CBL_STATE_DEF_t;
/** \}*/

typedef struct pe_info_s
{
    drv_timer_t swap_src_start_timer;
    drv_timer_t sender_response_timer;
    drv_timer_t src_cap_timer;
    drv_timer_t no_response_timer;
    drv_timer_t ps_transit_timer;
    drv_timer_t snk_request_timer;
    drv_timer_t snk_wait_cap_timer;
    drv_timer_t ps_src_on_timer;
    drv_timer_t src_transit_timer;
    drv_timer_t vcon_on_timer;
    drv_timer_t ps_src_off_timer;
#if VENDOR_DEFINE_ENABLED
    drv_timer_t dfp_ufp_vdm_disc_ident_timer;
    drv_timer_t disc_ident_timer;
    drv_timer_t vdm_response_timer;
#if VENDOR_DEFINE_MODE_ENABLED
    drv_timer_t vdm_mode_entry_timer;
    drv_timer_t vdm_mode_exit_timer;
#endif /* VENDOR_DEFINE_MODE_ENABLED */
#endif /* VENDOR_DEFINE_ENABLED */
    drv_timer_t ps_hard_reset_timer;
#if PE_BIST_CARRIER_MODE2_ENABLED
    drv_timer_t bist_cont_mode_timer; 
#endif /* PE_BIST_CARRIER_MODE2_ENABLED */
    drv_timer_t t_src_transition_timer;
    drv_timer_t t_fst_src_cap_timer;
    drv_timer_t t_new_src_timer;
    drv_timer_t t_src_recover_timer;
    drv_timer_t snk_hard_reset_timer;
    drv_timer_t pps_comm_timer;
    drv_timer_t prs_in_prog_timer;

    u32_t hard_reset_cnt:2;
    u32_t caps_cnt:6;
    u32_t disc_ident_cnt:5;
    u32_t prl_rst_cnt:3;
    u32_t hrst_sig_frm_phy:1;
    u32_t prl_txmsg_sent_ind:1;
    u32_t prl_msg_txerr:1;
    u32_t prl_msg2cbl_txerr:1;
    u32_t prl_rst_complete:1;
    u32_t cblrst_sig_frm_phy:1;
    u32_t entered_startup_dueto_pr_swp:1;
    u32_t modal_operation:1;
    u32_t swp_original_pr:1;
    u32_t error_recovery_directed:1;
    u32_t prs_in_prog:1;
    u32_t hrst_in_prog:1;
    u32_t pe_tx_sop_type:3;
    u32_t cable_rst_in_prog:1;

    u32_t pe_state:8; ///< PE current state
    u32_t pd_connected:1;
    u32_t pe_dfp_cbl_vdm_sop1_entered:1;
    u32_t pwr_changed:1; ///< power changed
    u32_t dpm_txmsg_type:8;
    u32_t pe_dfp_cbl_vdm_sop1_cmplt:1;
    u32_t pwr_transition_in_prog:1;
    u32_t rx_hard_reset_cnt:2;
    u32_t unexpected_msg_received:1;
    u32_t unsupported_msg_received:1;
    u32_t unrecognized_msg_received:1;
    u32_t interruptible_AMS_entered:1;
    u32_t non_interruptible_AMS_entered:1;
    u32_t tx_hard_reset_cnt:2;
    u32_t frs_detected:1;
    u32_t need_to_check_source_cap_send:1;

    sys_tick_t pd_connected_time;
    sys_tick_t chunk_packet_received_time;
    sys_tick_t ps_ready_start_time;
    
    u32_t src_ready_time;

} pe_info_t;
#pragma pack()

/** PE source port indication */
#define source_port() \
    ((g_pe_info.pe_state >= PE_SRC_STARTUP) && (g_pe_info.pe_state <= PE_SRC_DISABLED))

/** PE sink port indication */
#define sink_port() \
    ((g_pe_info.pe_state >= PE_SNK_STARTUP) && (g_pe_info.pe_state <= PE_SNK_TRANSIT_TO_DEFAULT))

/** PE source port in power negotiation */
#define source_in_pwr_negotiation() \
    ((g_pe_info.pe_state >= PE_SRC_STARTUP) && (g_pe_info.pe_state < PE_SRC_READY))

/** PE sink port in power negotiation */
#define sink_in_pwr_negotiation() \
    ((g_pe_info.pe_state >= PE_SNK_STARTUP) && (g_pe_info.pe_state < PE_SNK_READY))

/** PE in PS_READY */
#define pe_state_is_ps_rdy() \
    ((g_pe_info.pe_state == PE_SNK_READY) || (g_pe_info.pe_state == PE_SRC_READY))

/** PE in PE_SRC_READY */
#define pe_state_is_src_rdy() \
    (g_pe_info.pe_state == PE_SRC_READY)

/** PE in PE_SNK_READY */
#define pe_state_is_snk_rdy() \
    (g_pe_info.pe_state == PE_SNK_READY)


/** Get current PE state */
#define pe_state_get() \
    (g_pe_info.pe_state)

#if USBPD_DEBUG_ENABLED
/** Set current PE state */
void pe_state_set(u32_t sta);
#else
/** Set current PE state */
#define pe_state_set(val) \
    do { \
        g_pe_info.ps_ready_start_time = 0; \
        g_pe_info.pe_state = val; \
    } while(0)
#endif /* USBPD_DEBUG_ENABLED */


/** Get current hard reset tx count */
#define pe_tx_hard_reset_cnt_get() \
    (g_pe_info.tx_hard_reset_cnt)


#define pe_pwr_transition_in_prog() \
    (g_pe_info.pwr_transition_in_prog)

#define pe_pwr_transition_in_prog_set(st) \
    do { \
        g_pe_info.pwr_transition_in_prog = st; \
    } while(0)


#define pe_unexpected_msg_received() \
    (g_pe_info.unexpected_msg_received)

#define pe_unexpected_msg_received_set(st) \
    do { \
        g_pe_info.unexpected_msg_received = st; \
    } while(0)


#define pe_unsupported_msg_received() \
    (g_pe_info.unsupported_msg_received)

#define pe_unsupported_msg_received_set(st) \
    do { \
        g_pe_info.unsupported_msg_received = st; \
    } while(0)


#define pe_unrecognized_msg_received() \
    (g_pe_info.unrecognized_msg_received)

#define pe_unrecognized_msg_received_set(st) \
    do { \
        g_pe_info.unrecognized_msg_received = st; \
    } while(0)


#define pe_interruptible_AMS_entered_get() \
    (g_pe_info.interruptible_AMS_entered)

#if 0  /* modified by James Gan - 2019-10-30 */
#define pe_interruptible_AMS_entered_set(st) \
    do { \
        g_pe_info.interruptible_AMS_entered = st; \
    } while(0)
#else
void pe_interruptible_AMS_entered_set(bool_t st);
#endif /* #if 0 */


#define pe_non_interruptible_AMS_entered_get() \
    (g_pe_info.non_interruptible_AMS_entered)

#if 0  /* modified by James Gan - 2019-10-30 */
#define pe_non_interruptible_AMS_entered_set(st) \
    do { \
        g_pe_info.non_interruptible_AMS_entered = st; \
    } while(0)
#else
void pe_non_interruptible_AMS_entered_set(bool_t st);
#endif /* #if 0 */


#define pe_hard_reset_in_prog() \
    (g_pe_info.hrst_in_prog)

#define pe_hard_reset_in_prog_set(st) \
    do { \
        g_pe_info.hrst_in_prog = st; \
    } while(0)

/** Get current PE PD connected state */
#define pe_pd_connected_get() \
    (g_pe_info.pd_connected)

/** Set current PE PD connected state */
#define pe_pd_connected_set(st) \
    do { \
        g_pe_info.pd_connected = st; \
    } while(0)


/** Set hard reset signal from PHY flag */
#define pe_hrst_sig_frm_phy_set(flg) \
    do { \
        g_pe_info.hrst_sig_frm_phy = flg; \
    } while(0)

/** Get hard reset signal from PHY flag */
#define pe_hrst_sig_frm_phy_get() \
    (g_pe_info.hrst_sig_frm_phy)


/** Set protocol tx message indication flag */
#define pe_prl_txmsg_sent_ind_set(flg) \
    do { \
        g_pe_info.prl_txmsg_sent_ind = flg; \
    } while(0)

/** Get protocol tx message indication flag */
#define pe_prl_txmsg_sent_ind_get() \
    (g_pe_info.prl_txmsg_sent_ind)


/** Set protocol message tx error flag */
#define pe_prl_msg_txerr_set(flg) \
    do { \
        g_pe_info.prl_msg_txerr = flg; \
    } while(0)

/** Get protocol message tx error flag */
#define pe_prl_msg_txerr_get() \
    (g_pe_info.prl_msg_txerr)


/** Set protocol message to cable plug tx error flag */
#define pe_prl_msg2cbl_txerr_set(flg) \
    do { \
        g_pe_info.prl_msg2cbl_txerr = flg; \
    } while(0)

/** Get protocol message to cable plug tx error flag */
#define pe_prl_msg2cbl_txerr_get() \
    (g_pe_info.prl_msg2cbl_txerr)


/** Set protocol reset complete flag */
#define pe_prl_rst_complete_set(flg) \
    do { \
        g_pe_info.prl_rst_complete = flg; \
    } while(0)

/** Get protocol reset complete flag */
#define pe_prl_rst_complete_get() \
    (g_pe_info.prl_rst_complete)


/** Set PE error recovery_directed flag */
#define pe_error_recovery_directed_set(flg) \
    do { \
        g_pe_info.error_recovery_directed = flg; \
    } while(0)

/** Get PE error recovery_directed flag */
#define pe_error_recovery_directed_get() \
    (g_pe_info.error_recovery_directed)


/** Set PE power role swap in progress flag */
#if 0  /* modified by James Gan - 2019-10-30 */
#define pe_prs_in_prog_set(flg) \
    do { \
        if (flg) { \
            drv_timer_start(T_PRS_IN_PROG_TIMER, &(g_pe_info.prs_in_prog_timer), NULL); \
            if (!g_pe_info.prs_in_prog) { \
                usbpd_event_hook(prs_started,TRUE); \
            } \
        } else { \
        	drv_timer_stop(&(g_pe_info.prs_in_prog_timer)); \
            if (g_pe_info.prs_in_prog) { \
                usbpd_event_hook(prs_completed,TRUE); \
            } \
        } \
        g_pe_info.prs_in_prog = flg; \
    } while(0)
#else
void pe_prs_in_prog_set(bool_t flg);
#endif /* #if 0 */

/** Get PE power role swap in progress flag */
#define pe_prs_in_prog_get() \
    (g_pe_info.prs_in_prog)


/** Set PE cable reset in progress flag */
#define pe_cblrst_in_prog_set(flg) \
    do { \
        g_pe_info.cable_rst_in_prog = flg; \
    } while(0)

/** Get PE cable reset in progress flag */
#define pe_cblrst_in_prog_get() \
    (g_pe_info.cable_rst_in_prog)


#define pe_frs_detected() \
    (g_pe_info.frs_detected)

#define pe_frs_detected_set(st) \
    do { \
        g_pe_info.frs_detected = st; \
    } while(0)


#define pe_need_to_check_source_cap_send_get() \
    (g_pe_info.need_to_check_source_cap_send)

#define pe_need_to_check_source_cap_send_set(st) \
    do { \
        g_pe_info.need_to_check_source_cap_send = st; \
    } while(0)


/** Local hardware reset */
#define pe_local_hw_reset() \
    do { \
        dpm_tx_in_prog_set(FALSE); \
        prl_local_hw_reset_set(TRUE); \
        DRV_REG_FIELD_SET(DPM_PRL_REG,LOCAL_HW_RESET,TRUE); \
        delay(1); \
        DRV_REG_FIELD_SET(DPM_PRL_REG,LOCAL_HW_RESET,FALSE); \
    } while(0)


/** Protocol reset */
void pe_prl_reset();


/** Set DPM tx message type */
#define pe_dpm_txmsg_type_set(flg) \
    do { \
        g_pe_info.dpm_txmsg_type = flg; \
    } while(0)

/** Get DPM tx message type */
#define pe_dpm_txmsg_type_get() \
    (g_pe_info.dpm_txmsg_type)


/** Set entered start up state dueto PR swap flag */
#define pe_entered_startup_dueto_pr_swp_set(flg) \
    do { \
        g_pe_info.entered_startup_dueto_pr_swp = flg; \
    } while(0)

/** Get entered start up state dueto PR swap flag */
#define pe_entered_startup_dueto_pr_swp_get() \
    (g_pe_info.entered_startup_dueto_pr_swp)


/** Set cable plug reset signal from PHY */
#define pe_cblrst_sig_frm_phy_set(flg) \
    do { \
        g_pe_info.cblrst_sig_frm_phy = flg; \
    } while(0)

/** Get cable plug reset signal from PHY */
#define pe_cblrst_sig_frm_phy_get() \
    (g_pe_info.cblrst_sig_frm_phy)


/** Set modal operation flag */
#define pe_modal_operation_set(flg) \
    do { \
        g_pe_info.modal_operation = flg; \
    } while(0)

/** Get modal operation flag */
#define pe_modal_operation_get() \
    (g_pe_info.modal_operation)



#define pe_informed_cab_rst_get() \
    prl_pe_informed_cab_rst_get()

#define pe_informed_cab_rst_clear() \
    do { \
        prl_pe_informed_cab_rst_clear(); \
    } while(0)

#define pe_informed_hrst_get() \
    prl_pe_informed_hrst_get()

#define pe_informed_hrst_clear() \
    do { \
        prl_pe_informed_hrst_clear(); \
    } while(0)

#define hrst_req_frm_pe() \
    do { \
        prl_hrst_req_frm_pe_set(TRUE); \
    } while(0)

#define hrst_req_frm_pe_clear() \
    prl_hrst_req_frm_pe_set(FALSE)

#define cbl_rst_req_frm_pe() \
    do { \
        prl_cbl_rst_req_frm_pe_set(TRUE); \
    } while(0)

#define cbl_rst_req_frm_pe_clear() \
    prl_cbl_rst_req_frm_pe_set(FALSE)

#define cbl_rst_cmplt_frm_pe() \
    prl_cbl_rst_cmplt_frm_pe_set(TRUE)


#define hrst_cmplt_frm_pe() \
    do { \
        prl_hrst_cmplt_frm_pe_set(TRUE); \
    } while(0)


/** Set DFP to CBL sop' VDM entered flag */
#define pe_dfp_cbl_vdm_sop1_entered_set(flg) \
    do { \
        g_pe_info.pe_dfp_cbl_vdm_sop1_entered = flg; \
    } while(0)

/** Get DFP to CBL sop' VDM entered flag */
#define pe_dfp_cbl_vdm_sop1_entered_get() \
    (g_pe_info.pe_dfp_cbl_vdm_sop1_entered)

/** Set DFP to CBL sop' VDM complete flag */
#define pe_dfp_cbl_vdm_sop1_cmplt_set(flg) \
    do { \
        g_pe_info.pe_dfp_cbl_vdm_sop1_cmplt = flg; \
    } while(0)

/** Get DFP to CBL sop' VDM complete flag */
#define pe_dfp_cbl_vdm_sop1_cmplt_get() \
    (g_pe_info.pe_dfp_cbl_vdm_sop1_cmplt)


/** Set power changed flag */
#define pe_pwr_changed_set(flg) \
    do { \
        g_pe_info.pwr_changed = flg; \
    } while(0)

/** Get power changed flag */
#define pe_pwr_changed_get() \
    (g_pe_info.pwr_changed)


/** Set PE tx sop type */
#define pe_tx_sop_type_set(flg) \
    do { \
        g_pe_info.pe_tx_sop_type = flg; \
    } while(0)

/** Get PE tx sop type */
#define pe_tx_sop_type_get() \
    (g_pe_info.pe_tx_sop_type)


/** Set PE pd_connected_time */
#define pe_pd_connected_time_set(flg) \
    do { \
        g_pe_info.pd_connected_time = flg; \
    } while(0)

/** Get PE pd_connected_time */
#define pe_pd_connected_time_get() \
    (g_pe_info.pd_connected_time)


/** Set PE chunk_packet_received_time */
#define pe_chunk_packet_received_time_set(flg) \
    do { \
        g_pe_info.chunk_packet_received_time = flg; \
    } while(0)

/** Get PE chunk_packet_received_time */
#define pe_chunk_packet_received_time_get() \
    (g_pe_info.chunk_packet_received_time)


/** Set PE ps_ready_start_time */
#define pe_ps_ready_start_time_set(flg) \
    do { \
        g_pe_info.ps_ready_start_time = flg; \
    } while(0)

/** Get PE ps_ready_start_time */
#define pe_ps_ready_start_time_get() \
    (g_pe_info.ps_ready_start_time)




#define request_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == REQUEST_MSG))

#define get_source_cap_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_SRC_CAP_MSG))

#define dr_swp_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == DR_SWP_MSG))

#define pr_swp_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == PR_SWP_MSG))

#define get_snk_cap_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_SNK_CAP_MSG))

#define vcon_swp_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VCON_SWP_MSG))

#define vdm_disc_ident_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_IDENT_CMD_MSG))

#define vdm_disc_svid_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_SVID_CMD_MSG))

#define vdm_disc_mode_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_MODE_CMD_MSG))

#define vdm_enter_mode_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_ENTER_MODE_CMD_MSG))

#define vdm_exit_mode_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_EXIT_MODE_CMD_MSG))

#define vdm_attention_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_ATTENTION_CMD_MSG))

#define bist_receive_mode_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == BIST_RECEIVE_MODE_MSG))

#define bist_transmit_mode_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == BIST_TRANSMIT_MODE_MSG))

#define bist_carrier_mode2_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == BIST_CARRIER_MODE2_MSG))

#define bist_test_data_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == BIST_TEST_DATA))

#define snk_cap_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == SNK_CAP_MSG))

#define accept_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == ACCEPT_MSG))

#define src_cap_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == SRC_CAP_MSG))

#define reject_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == REJECT_MSG))

#define wait_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == WAIT_MSG))

#define ps_rdy_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == PS_RDY_MSG))

#define goto_min_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GOTO_MIN_MSG))

#define ping_msg_received() \
    ( dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == PING_MSG))

#define soft_reset_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == SOFT_RST_MSG))

#define vdm_disc_ident_ack_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_IDENT_ACK_CMD_MSG))

#define vdm_disc_ident_nak_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_IDENT_NAK_CMD_MSG))

#define vdm_disc_ident_busy_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_IDENT_BUSY_CMD_MSG))

#define vdm_disc_svid_ack_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_SVID_ACK_CMD_MSG))

#define vdm_disc_svid_nak_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_SVID_NAK_CMD_MSG))

#define vdm_disc_svid_busy_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_SVID_BUSY_CMD_MSG))

#define vdm_disc_mode_ack_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_MODE_ACK_CMD_MSG))

#define vdm_disc_mode_nak_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_MODE_NAK_CMD_MSG))

#define vdm_disc_mode_busy_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_DISC_MODE_BUSY_CMD_MSG))

#define vdm_enter_mode_ack_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_ENTER_MODE_ACK_CMD_MSG))

#define vdm_enter_mode_nak_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_ENTER_MODE_NAK_CMD_MSG))

#define vdm_enter_mode_busy_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_ENTER_MODE_BUSY_CMD_MSG))

#define vdm_exit_mode_ack_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_EXIT_MODE_ACK_CMD_MSG))

#define vdm_exit_mode_nak_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_EXIT_MODE_NAK_CMD_MSG))

#define vdm_exit_mode_busy_cmd_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == VDM_EXIT_MODE_BUSY_CMD_MSG))

#define reserved_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == RESERVED_MSG))

#define not_supported_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == NOT_SUPPORTED_MSG))

#define get_src_cap_ext_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_SRC_CAP_EXT_MSG))

#define get_status_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_STATUS_MSG))

#define fr_swap_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == FR_SWAP_MSG))

#define get_pps_status_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_PPS_STATUS_MSG))

#define get_country_codes_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_CTRY_CODES_MSG))

#define get_snk_cap_ext_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_SNK_CAP_EXT_MSG))

#define battery_status_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == BATTERY_STATUS_MSG))

#define alert_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == ALERT_MSG))

#define get_country_info_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_CTRY_INFO_MSG))

#define ext_msg_src_cap_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_SRC_CAP))

#define ext_msg_status_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_STATUS))

#define ext_msg_get_bat_cap_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_GET_BAT_CAP))

#define ext_msg_get_bat_status_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_GET_BAT_STATUS))

#define ext_msg_bat_cap_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_BAT_CAP))

#define ext_msg_get_mfr_info_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_GET_MFR_INFO))

#define ext_msg_mfr_info_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_MFR_INFO))

#define ext_msg_secur_req_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_SECUR_REQ))

#define ext_msg_secur_resp_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_SECUR_RESP))

#define ext_msg_fw_up_req_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_FW_UP_REQ))

#define ext_msg_fw_up_resp_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_FW_UP_RESP))

#define ext_msg_pps_status_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_PPS_STATUS))

#define ext_msg_country_info_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_COUNTRY_INFO))

#define ext_msg_country_codes_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_COUNTRY_CODES))

#define ext_msg_snk_cap_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == EXT_MSG_SNK_CAP))

#define get_country_info_msg_received() \
    (dpm_pe_rxmsg_ind_get() && (dpm_pe_rxmsg_type_get() == GET_CTRY_INFO_MSG))


#define src_cap_msg_sent() \
    ((pe_dpm_txmsg_type_get() == SRC_CAP_MSG) && pe_prl_txmsg_sent_ind_get())

#define ping_msg_sent() \
    ((pe_dpm_txmsg_type_get() == PING_MSG) && pe_prl_txmsg_sent_ind_get())

#define reject_msg_sent() \
    ((pe_dpm_txmsg_type_get() == REJECT_MSG) && pe_prl_txmsg_sent_ind_get())

#define wait_msg_sent() \
    ((pe_dpm_txmsg_type_get() == WAIT_MSG) && pe_prl_txmsg_sent_ind_get())

#define accept_msg_sent() \
    ((pe_dpm_txmsg_type_get() == ACCEPT_MSG) && pe_prl_txmsg_sent_ind_get())

#define goto_min_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GOTO_MIN_MSG) && pe_prl_txmsg_sent_ind_get())

#define snk_cap_msg_sent() \
    ((pe_dpm_txmsg_type_get() == SNK_CAP_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_src_cap_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_SRC_CAP_MSG) && pe_prl_txmsg_sent_ind_get())
 
#define ps_rdy_msg_sent() \
    ((pe_dpm_txmsg_type_get() == PS_RDY_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_disc_ident_ack_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_IDENT_ACK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
 
#define vdm_disc_svid_ack_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_SVID_ACK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_disc_mode_ack_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_MODE_ACK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_mode_entry_ack_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_ENTER_MODE_ACK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
  
#define vdm_mode_entry_nak_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_ENTER_MODE_NAK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_mode_exit_ack_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_EXIT_MODE_ACK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
  
#define vdm_mode_exit_nak_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_EXIT_MODE_NAK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_attention_cmd_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_ATTENTION_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
  
#define vdm_disc_ident_nak_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_IDENT_NAK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
 
#define vdm_disc_ident_busy_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_IDENT_BUSY_CMD_MSG) && pe_prl_txmsg_sent_ind_get())

#define vdm_disc_svid_nak_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_SVID_NAK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
 
#define vdm_disc_svid_busy_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_SVID_BUSY_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
 
#define vdm_disc_mode_nak_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_MODE_NAK_CMD_MSG) && pe_prl_txmsg_sent_ind_get())
   
#define vdm_disc_mode_busy_msg_sent() \
    ((pe_dpm_txmsg_type_get() == VDM_DISC_MODE_BUSY_CMD_MSG) && pe_prl_txmsg_sent_ind_get())


#define not_supported_msg_sent() \
    ((pe_dpm_txmsg_type_get() == NOT_SUPPORTED_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_src_cap_ext_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_SRC_CAP_EXT_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_status_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_STATUS_MSG) && pe_prl_txmsg_sent_ind_get())

#define fr_swap_msg_sent() \
    ((pe_dpm_txmsg_type_get() == FR_SWAP_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_pps_status_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_PPS_STATUS_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_country_codes_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_CTRY_CODES_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_snk_cap_ext_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_SNK_CAP_EXT_MSG) && pe_prl_txmsg_sent_ind_get())

#define battery_status_msg_sent() \
    ((pe_dpm_txmsg_type_get() == BATTERY_STATUS_MSG) && pe_prl_txmsg_sent_ind_get())

#define alert_msg_sent() \
    ((pe_dpm_txmsg_type_get() == ALERT_MSG) && pe_prl_txmsg_sent_ind_get())

#define get_country_info_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_CTRY_INFO_MSG) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_src_cap_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_SRC_CAP) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_status_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_STATUS) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_get_bat_cap_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_GET_BAT_CAP) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_get_bat_status_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_GET_BAT_STATUS) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_bat_cap_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_BAT_CAP) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_get_mfr_info_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_GET_MFR_INFO) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_mfr_info_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_MFR_INFO) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_secur_req_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_SECUR_REQ) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_secur_resp_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_SECUR_RESP) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_fw_up_req_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_FW_UP_REQ) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_fw_up_resp_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_FW_UP_RESP) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_pps_status_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_PPS_STATUS) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_country_info_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_COUNTRY_INFO) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_country_codes_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_COUNTRY_CODES) && pe_prl_txmsg_sent_ind_get())

#define ext_msg_snk_cap_sent() \
    ((pe_dpm_txmsg_type_get() == EXT_MSG_SNK_CAP) && pe_prl_txmsg_sent_ind_get())

#define get_country_info_msg_sent() \
    ((pe_dpm_txmsg_type_get() == GET_CTRY_INFO_MSG) && pe_prl_txmsg_sent_ind_get())

extern volatile pe_info_t g_pe_info;

void pe_state_init();
void pe_state_release();
void pe_state_machine();
void pe_src_startup();
void pe_snk_startup();
void pe_src_ready();
void pe_snk_ready();
void pe_cbl_state_machine();
void pe_txmsg_req(u32_t msg_type);
void pe_txmsg_req_ex(u32_t msg_type, u32_t sop_type);
void pe_tx_ind_start_timer();
void pe_disabled_vdm_got_req();
void pe_disabled_vdm_send_resp();
void pe_snk_wait_for_cap();
void pe_src_send_soft_reset();
void pe_snk_send_soft_reset();
#if VENDOR_DEFINE_ENABLED
void pe_dfp_ufp_vdm_identity_req();
#endif

#endif /* #ifndef __PE_STATE_H_ */

