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

#include "sys_defs.h"
#include "sys_gpio.h"
#include "prl_msg_defs.h"
#include "usbpd.h"
#include "drivers.h"
#include "sys_reg.h"

#pragma pack(1)


/** System continuous timer timeout value, unit is millisecond */
#define SYS_CONTINUOUS_TIMER_TIMEOUT            (10U)

#define SYS_STARTUP_DELAY_TIMEOUT               (50U)
#define SYS_LED_FLASH_TIMEOUT                   (100U)
#define SYS_PPS_REQUEST_TIMEOUT                 (500U)
#define SYS_REG_PPS_REQUEST_TIMEOUT             (600U)

typedef enum SYS_PD_LED_STATE_e
{
    SYS_PD_LED_STATE_OFF,
    SYS_PD_LED_STATE_ON,
    SYS_PD_LED_STATE_FLASH,
    SYS_PD_LED_STATE_FLASH_FAST,
    SYS_PD_LED_STATE_FLASH_INVALID
} SYS_PD_LED_STATE_t;

typedef struct SYS_PD_INFO_s
{
    sys_tick_t current_time;
    drv_timer_t continuous_timer;
    u32_t continuous_timer_tick;

    u32_t vbus_current:16;
    u32_t ibus_current:16;

    u32_t vbus_requested:16;
    u32_t ibus_requested:16;

    u32_t pdo_vbus:16;
    u32_t pdo_ibus:16;

    UPD_EXT_MSG_GET_MFR_INFO_t rx_get_mfr_info;

    u32_t display_state:1;
    u32_t led_state:4;
    u32_t led_display_flash_interval:16;
    u32_t digit_display_mode:4;
    u32_t digit_display_next_mode:4;
    u32_t reserved1:3;

    u32_t led_on_start_tick;

    u32_t vbus_source_en:1,
		  sys_initializing:1,
		  c2_cable_done_flag:1,
		  invalid_bat_sta_ref:1,
		  invalid_bat_cap_ref:1,
		  snk_request_current_state:1,  /** snk request current state */
          snk_request_last_state:1,     /** snk request last state */
          snk_request_is_need:1,        /** snk request is need flag */
          snk_request_auto_is_need:1,   /** auto snk request is need flag */
          snk_request_auto_pps:1,       /** auto snk request PPS flag */
          auto_epr_request_flg:1,
          snk_request_pps_in_epr_mode:1,
          snk_request_pps_index_in_epr_mode:4,
          snk_request_epr_after_pps:1,
          snk_request_epr_index_after_pps:4,
          reserved2:11;

    sys_tick_t snk_request_on_start_time; /** the start time of snk request is on */

    sys_tick_t snk_request_on_last_time; /** the last time of snk request is on */

    drv_timer_t snk_request_timer;

    u32_t rx_pkt_cnt;

    u32_t tx_pkt_cnt;

    u32_t pps_request_start_tick;

    sys_tick_t int_high_start_time;

    SYS_REG_PDO_INFO_t pdo_info;
    SYS_REG_MCU_CTRL_t mcu_ctrl;
    SYS_REG_STATUS_t status;
    u8_t operation_failure;

} SYS_PD_INFO_t;

#pragma pack()

extern volatile SYS_PD_INFO_t g_sys_pd_info;

/** \brief Get PD C1 ibus value
 */
#define sys_pd_ibus_get()   drv_adc_ibus_get(SYS_CURRENT_SENCE_SAMPLE_RESISTER)

/** \brief Get LED state
 */
#define sys_pd_led_state_get()      (g_sys_pd_info.led_state)

/** \brief Set LED state
 *
 * \param state     defined by SYS_PD_LED_STATE_t
 */
void sys_pd_led_state_set(SYS_PD_LED_STATE_t state);


/** \brief Configuration channel(CC) hook when in Unattached.SNK
 */
void sys_pd_sink_unattached_hook();

/** \brief CC hook when in AttachWait.SNK
 */
void sys_pd_sink_attachwait_hook();

/** \brief CC hook when in Attached.SNK
 */
void sys_pd_sink_attached_hook();

/** \brief PD hook while sink mode require new power transition
 *
 * \return              see the error code of status_t
 */
status_t sys_pd_sink_transit_to_new_power_hook();

/** \brief CC hook when in Unattached.SRC
 *
 */
void sys_pd_source_unattached_hook();

/** \brief CC hook when in AttachWait.SRC
 *
 */
void sys_pd_source_attachwait_hook();

/** \brief CC hook when in Attached.SRC
 *
 */
void sys_pd_source_attached_hook();

/** \brief PD hook while source require new power transition
 *
 * \param pos           the position of source capabilities
 * \return              see the error code of status_t
 */
status_t sys_pd_source_transit_to_new_power_hook(u32_t pos);

/** \brief CC or PD hook when get PD VBUS source enable status
 *
 * \return              0: disabled, 1: enabled
 */
bool_t sys_pd_vbus_source_en_get(void);

/** \brief CC or PD hook when enable or disable PD VBUS sourcing
 *
 * \param flg           0: disable, 1: enable
 */
void sys_pd_vbus_source_en_set(bool_t flg);

/** \brief CC or PD hook when get PD VBUS source enable discharge
 *
 * \return              0: disabled, 1: enabled
 */
bool_t sys_pd_vbus_discharge_en_get(void);

/** \brief CC or PD hook when enable or disable PD VBUS discharge
 *
 * \param flg           0: disable, 1: enable
 */
void sys_pd_vbus_discharge_en_set(bool_t flg);

/** \brief CC or PD hook when get PD CC1 VCONN source enable status
 *
 * \return              0: disabled, 1: enabled
 */
bool_t sys_pd_cc1_vconn_en_get(void);

/** \brief CC or PD hook when enable or disable PD CC1 VCONN sourcing
 *
 * \param flg           0: disable, 1: enable
 */
void sys_pd_cc1_vconn_en_set(bool_t flg);

/** \brief CC or PD hook when get PD CC2 VCONN source enable status
 *
 * \return              0: disabled, 1: enabled
 */
bool_t sys_pd_cc2_vconn_en_get(void);


/** \brief PD hook when power role swap started
 *
 * \param arg           unused argument
 */
void sys_pd_prs_started_hook(u32_t arg);

/** \brief PD hook when power role swap completed
 *
 * \param arg           unused argument
 */
void sys_pd_prs_completed_hook(u32_t arg);


/** \brief PD hook when data role swap started
 *
 * \param arg           unused argument
 */
void sys_pd_drs_started_hook(u32_t arg);

/** \brief PD hook when data role swap completed
 *
 * \param arg           unused argument
 */
void sys_pd_drs_completed_hook(u32_t arg);


/** \brief PD hook when vconn source swap started
 *
 * \param arg           unused argument
 */
void sys_pd_vcs_started_hook(u32_t arg);

/** \brief PD hook when vconn source swap completed
 *
 * \param arg           unused argument
 */
void sys_pd_vcs_completed_hook(u32_t arg);

/** \brief PD power change request hook
 *
 * \param arg           unused argument
 */
void sys_pd_power_change_req_hook(u32_t arg);

/** \brief PD hook when message received
 *
 * \param arg           unused argument
 */
void sys_pd_prl_msg_received_hook(u32_t arg);

/** \brief PD hook when message sent
 *
 * \param arg           unused argument
 */
void sys_pd_prl_msg_sent_hook(u32_t arg);

/** \brief PD task IDLE hook when task is IDLE
 *
 * \param arg           unused argument
 */
void sys_pd_idle_hook(u32_t arg);

/** \brief PD hook when VDM discover identity response ack is received
 *
 * \param arg           unused argument
 */
void sys_pd_vdm_disc_ident_ack_received_hook(u32_t arg);

/** \brief PD hook when received or transmited VDM Attention message
 *
 * \param p_info        Pointer to PD UPD_DATA_MSG_VDM_ATTENTION_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_vdm_attention_hook(UPD_DATA_MSG_VDM_ATTENTION_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited Unstructured VDM message
 *
 * \param p_msg         Pointer to PD message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_vdm_unstructured_hook(u8_t *p_msg, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited alert message
 *
 * \param p_info        Pointer to PD UPD_DATA_MSG_ALERT_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_alert_hook(UPD_DATA_MSG_ALERT_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received get country info message
 *
 * \param p_info        Pointer to PD UPD_DATA_MSG_GET_COUNTRY_INFO_t message
 */
void sys_pd_prl_msg_get_country_info_hook(UPD_DATA_MSG_GET_COUNTRY_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received battery status message
 *
 * \param p_info        Pointer to PD UPD_DATA_MSG_BATTERY_STATUS_t message
 */
void sys_pd_prl_msg_battery_status_hook(UPD_DATA_MSG_BATTERY_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/*  == Extended message hook ==  */

/** \brief PD hook when received or transmited extended source capability message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_SRC_CAP_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_src_cap_hook(UPD_EXT_MSG_SRC_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended status message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_STATUS_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_status_hook(UPD_EXT_MSG_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended get battery capability message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_GET_BAT_CAP_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_get_bat_cap_hook(UPD_EXT_MSG_GET_BAT_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended get battery status message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_GET_BAT_STATUS_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_get_bat_status_hook(UPD_EXT_MSG_GET_BAT_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended battery capability message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_BAT_CAP_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_bat_cap_hook(UPD_EXT_MSG_BAT_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended get manufacturer information message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_GET_MFR_INFO_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_get_mfr_info_hook(UPD_EXT_MSG_GET_MFR_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended manufacturer information message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_MFR_INFO_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_mfr_info_hook(UPD_EXT_MSG_MFR_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended security request message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_SECURITY_REQ_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_secur_req_hook(UPD_EXT_MSG_SECURITY_REQ_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended security response message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_SECURITY_RESP_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_secur_resp_hook(UPD_EXT_MSG_SECURITY_RESP_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended firmware upgrade request message
 *
 * \param p_info        Pointer to PD firmware upgrade request message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_fw_up_req_hook(void *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended firmware upgrade response message
 *
 * \param p_info        Pointer to PD firmware upgrade response message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_fw_up_resp_hook(void *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended PPS status message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_PPS_STATUS_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_pps_status_hook(UPD_EXT_MSG_PPS_STATUS_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended country info message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_COUNTRY_INFO_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_country_info_hook(UPD_EXT_MSG_COUNTRY_INFO_t *p_info, PRL_MSG_DIR_TYPE_t dir);

/** \brief PD hook when received or transmited extended country codes message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_COUNTRY_CODES_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_country_codes_hook(UPD_EXT_MSG_COUNTRY_CODES_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook when received or transmited extended sink capability message
 *
 * \param p_info        Pointer to PD UPD_EXT_MSG_SNK_CAP_t message
 * \param dir           The hook call from receiving or transmiting, 0: rx, 1: tx
 */
void sys_pd_prl_msg_ext_snk_cap_hook(UPD_EXT_MSG_SNK_CAP_t *p_info, PRL_MSG_DIR_TYPE_t dir);


/** \brief PD hook initialization, need to be called in system init
 *
 */
void sys_pd_hook_init();

bool_t sys_new_power_level_req();

#endif /* #ifndef __SYS_PD_HOOK_H_ */

