/**
  *****************************************************************************
  * @file    ufcs_defs.h
  * @author  Solution Team
  * @version V1.00
  * @date    28-February-2023
  * @brief   UFCS feature definitions
  *****************************************************************************
  * @attention 
  *  Copyright (c) 2017 - 2023 Unicmicro Co., Ltd. 
  *  All Rights Reserved. 
  *****************************************************************************
  */
 
#ifndef __UFCS_DEFS_H_
#define __UFCS_DEFS_H_


#include "libc.h"
#include "drivers.h"
#include "ufcs_msg_defs.h"


#pragma pack(1)

/** 协议版本1.0 */
#define UFCS_SPEC_VER_10                        (1)

typedef enum UFCS_DEV_ID_e
{
    UFCS_DEV_ID_0,		                        /* 设备ID0 */
    UFCS_DEV_ID_1,                              /* 设备ID1 */
    UFCS_DEV_ID_MAX
} UFCS_DEV_ID_t;

/** 调试使能开关 */
#define UFCS_DEBUG_ENABLED                      (1)
typedef enum UFCS_DEBUG_LEVEL_e
{
    UFCS_DEBUG_LEVEL_OFF,		                /* 关闭调试 */
    UFCS_DEBUG_LEVEL_1,                         /* 调试等级1，开启 */
    UFCS_DEBUG_LEVEL_2,                         /* 调试等级2，详细 */
    UFCS_DEBUG_LEVEL_3,                         /* 调试等级3，详细+ */
    UFCS_DEBUG_LEVEL_4,                         /* 调试等级4，含中断信息 */
    UFCS_DEBUG_LEVEL_END
} UFCS_DEBUG_LEVEL_t;


/** 默认软硬件版本 */
#define UFCS_DEF_HARDWARE_VERSION               (1)
#define UFCS_DEF_FIRMWARE_VERSION               (1)

/** 抓包模式开关 */
#define UFCS_CAPTURE_MODE_ENABLED               (0)

/** 接收中断模式使能 */
#define UFCS_RX_INTR_MODE_ENABLED               (0)

/** 电流值宏定义：输入: mA, 输出 1/10 */
#define UFCS_CURRENT_DIV                        10U
#define UFCS_CURRENT_VAL(v)                     ((v)/UFCS_CURRENT_DIV)

/** 电压值宏定义：输入: mV, 输出 1/10 */
#define UFCS_VOLTAGE_DIV                        10U
#define UFCS_VOLTAGE_VAL(v)                     ((v)/UFCS_VOLTAGE_DIV)

/** 电压调节步进 */
typedef enum UFCS_VOLTAGE_STEP_e
{
    UFCS_VOLTAGE_STEP_10mV,		                /* 电压调节步进10mV */
    UFCS_VOLTAGE_STEP_20mV,                     /* 电压调节步进20mV */
    UFCS_VOLTAGE_STEP_END
} UFCS_VOLTAGE_STEP_t;

/** 电流调节步进 */
typedef enum UFCS_CURRENT_STEP_e
{
    UFCS_CURRENT_STEP_10mA,                     /* 电流调节步进10mA */
    UFCS_CURRENT_STEP_20mA,                     /* 电流调节步进20mA */
    UFCS_CURRENT_STEP_30mA,		                /* 电流调节步进30mA */
    UFCS_CURRENT_STEP_40mA,                     /* 电流调节步进40mA */
    UFCS_CURRENT_STEP_50mA,		                /* 电流调节步进50mA */
    UFCS_CURRENT_STEP_END
} UFCS_CURRENT_STEP_t;

/** 安全0V */
#define UFCS_VSAFE_0V_MAX                       600U

/** 安全5V */
#define UFCS_VSAFE_5V                           5000U
#define UFCS_VSAFE_5V_DISCONNECT                3400U
#define UFCS_VSAFE_5V_MIN                       4400U
#define UFCS_VSAFE_5V_MAX                       5500U

/** 标准电压定义 */
#define UFCS_VOLTAGE_5V                         UFCS_VSAFE_5V
#define UFCS_VOLTAGE_9V                         9000U
#define UFCS_VOLTAGE_12V                        12000U
#define UFCS_VOLTAGE_15V                        15000U
#define UFCS_VOLTAGE_20V                        20000U
#define UFCS_VOLTAGE_28V                        28000U
#define UFCS_VOLTAGE_36V                        36000U
#define UFCS_VOLTAGE_48V                        48000U

/** 获取电源配置输出值 */
#define UFCS_MIN_CURR_GET(obj)                  (((obj)->min_curr))
#define UFCS_MAX_CURR_GET(obj)                  (((obj)->max_curr))
#define UFCS_MIN_VOLT_GET(obj)                  ((((obj)->min_volt_h) << 8) + ((obj)->min_volt_l))
#define UFCS_MAX_VOLT_GET(obj)                  (((obj)->max_volt))

/** 电源配置默认输出编号 */
#define UFCS_DEF_OUTPUT_IDX                     (0)
/** 电源配置最大输出模式数 */
#define UFCS_MAX_OUTPUT_CAP_NUM                 (7)


/** 设备配置 */
typedef struct UFCS_DEV_CFG_s
{
    u32_t enable:1,                     /* UFCS功能使能，0: 关闭, 1: 开启 */
          debug:3,                      /* 调试等级，0: 关闭, 1: 开启, 2: 详细, 3: 详细+; 4: 含中断信息 */
          capture_mode:1,               /* 抓包模式，0: 关闭, 1: 使能 */
          dev_type:3,                   /* 设备类型，1: 供电设备, 2: 充电设备, 3: 线缆电子标签 */

          output_ovp_en:1,              /* 输出OVP, 0: 关闭, 1:使能 */
          output_uvp_en:1,              /* 输出UVP, 0: 关闭, 1:使能 */
          output_ocp_en:1,              /* 输出OCP, 0: 关闭, 1:使能 */
          output_scp_en:1,              /* 输出SCP, 0: 关闭, 1:使能 */
          usb_otp_en:1,                 /* USB接口 OTP, 0: 关闭, 1:使能 */
          dev_bat_otp_en:1,             /* 设备内部/电池 OTP, 0: 关闭, 1:使能 */
          cc_ovp_en:1,                  /* CC OVP, 0: 关闭, 1:使能 */
          dm_ovp_en:1,                  /* D- OVP, 0: 关闭, 1:使能 */

          dp_ovp_en:1,                  /* D+ OVP, 0: 关闭, 1:使能 */
          input_ovp_en:1,               /* 输入OVP, 0: 关闭, 1:使能 */
          input_uvp_en:1,               /* 输入UVP, 0: 关闭, 1:使能 */
          leakage_en:1,                 /* 漏电流超标, 0: 关闭, 1:使能 */
          vbus_lost_en:1,               /* 输入掉电, 0: 关闭, 1:使能 */
          crc_protect_en:1,             /* CRC 异常关闭输出, 0: 关闭, 1:使能 */
          cbl_det_en:1,                 /* 线缆检测开关, 0: 关闭, 1:使能 */
          src_vbus_check:1,             /* 供电设备检测输出是否达标, 0: 关闭, 1:使能 */

          n_get_output_cap:2,           /* 获取输出能力次数，0为不重新获取 */
          spec_rev:6;                   /* 协议版本编号 */

    u32_t wdt_timeout:16,               /* 看门狗定时器溢出时间，单位ms，默认1000ms */
          ic_ver:16;                    /* 芯片版本号 */

    u32_t hw_ver:16,                    /* 硬件版本号 */
          fw_ver:16;                    /* 软件版本号 */

    /** 设备电源、温度配置 */
    union {
        struct {
            u32_t output_num:4,         /* 最大输出模式数 */
                  power_changed:1,      /* 电源配置修改标志，如果修改过，则请置1 */
                  reserved2:11,         /* 保留 */
                  max_temperature:8,    /* 设备内部最大允许温度 */
                  max_usb_temperature:8;/* 设备USB接口最大允许温度 */

            UFCS_DATA_MSG_OUTPUT_CAP_t output[UFCS_MAX_OUTPUT_CAP_NUM]; /* 输出模式 */
        } src;

        struct {
            u32_t max_curr:16,          /* 最大工作电流，单位 10mA */
                  max_volt:16;          /* 最大工作电流，单位 10mA */

            u32_t opr_curr:16,          /* 当前工作电流，单位 10mA */
                  opr_volt:16;          /* 当前工作电压，单位 10mV */

            u32_t volt_step_type:1,     /* 电压调节最小步进: 0b：10mV, 1b：20mV */
                  curr_step_type:3,     /* 电流调节最小步进：000b：10mA，001b：20mA，010b：30mA，011b：40mA，100b：50mA，其它：保留 */
                  n_ping_retry_cnt:4,   /* 充电设备发送PING的次数，默认为5次 */
                  reserved2:8,          /* 保留 */
                  max_temperature:8,    /* 设备电池最大允许温度 */
                  max_usb_temperature:8;/* 设备USB接口最大允许温度 */

            u32_t volt_step:16,         /* 电压调节步进，默认200mV */
                  curr_step:16;         /* 电流调节步进，默认200mA */

            u32_t reserved3[11];        /* 保留 */
        } snk;

        struct {
            u32_t max_curr:8,           /* 最大承载电流，单位 1A */
                  max_volt:8,           /* 最大承载电压，单位 1V */
                  impedance:16;         /* 线缆阻抗，单位 mOh */

            u32_t reserved2[14];        /* 保留 */
        } cbl;
    } u_params;

} UFCS_DEV_CFG_t;


enum UFCS_PHY_RATE_e
{
    UFCS_PHY_RATE_115200 = 115200,
    UFCS_PHY_RATE_57600  = 57600,
    UFCS_PHY_RATE_38400  = 38400
};

enum UFCS_PHY_STATE_e
{
    UFCS_PHY_STATE_DISABLED,
    UFCS_PHY_STATE_ENABLED,
    UFCS_PHY_STATE_HIGH_IMPEDANCE,
    UFCS_PHY_STATE_RESTORE,
    UFCS_PHY_STATE_CABLE_RESET,
    UFCS_PHY_STATE_DEVICE_RESET,
    UFCS_PHY_STATE_END
};

typedef enum UFCS_PHY_MODE_e
{
    UFCS_PHY_MODE_HIGH_IMPEDANCE,
    UFCS_PHY_MODE_SHORT,
    UFCS_PHY_MODE_OPEN,
    UFCS_PHY_MODE_LOAD_GND,
    UFCS_PHY_MODE_LOAD_0P6V,
    UFCS_PHY_MODE_LOAD_3P3V,
    UFCS_PHY_MODE_END
} UFCS_PHY_MODE_t;

typedef enum UFCS_PHY_INTF_e
{
    UFCS_PHY_INTF_TX,
    UFCS_PHY_INTF_RX,
    UFCS_PHY_INTF_END
} UFCS_PHY_INTF_t;

#define N_DET_RETRY_COUNT       (3)     /* 识别检测计数阈值 */
#define UFCS_PHY_MIN_VOLT1      (900)
#define UFCS_PHY_MIN_VOLT2      (1420)

/* 协议层物理层结构定义 */
typedef struct UFCS_PHY_INFO_s
{
	u32_t tx_pin:8,                     /* 物理层发送引脚 */

          rx_pin:8,                     /* 物理层接收引脚 */

          state:4,                      /* 物理层状态标志 */
          state_prev:4,                 /* 物理层前一状态标志 */

          configured_flag:1,            /* 物理层配置过标志 */
          tx_pin_origin_gpio_en:1,      /* 物理层发送引脚的GPIO_EN原始状态 */
          tx_pin_origin_gpio_oe:1,      /* 物理层发送引脚的GPIO_OE原始状态 */
          rx_pin_origin_gpio_en:1,      /* 物理层接收引脚的GPIO_EN原始状态 */
          rx_pin_origin_gpio_oe:1,      /* 物理层接收引脚的GPIO_OE原始状态 */
          origin_gpio_state_saved:1,    /* 已保存GPIO原始状态 */
          reserved:2;                   /* 保留 */

    u32_t baudrate;                     /* 当前波特率 */
    u32_t baudrate_prev;                /* 前一次的波特率 */

    /** 物理层配置函数，有默认函数，用户也可以替换 */
    void (*config)(u32_t dev_ptr);

    /** 物理层设置PHY模式函数 */
    void (*mode_set)(u32_t dev_ptr, UFCS_PHY_MODE_t tx, UFCS_PHY_MODE_t rx);

    /** 物理层获取接口电压函数, type: tx = 0, rx = 1 */
    u32_t (*volt_get)(u32_t dev_ptr, UFCS_PHY_INTF_t type);

    /** 物理层DMA发送完成中断服务函数，有默认函数，用户也可以替换 */
    void (*dma_tx_isr)(u32_t dev_ptr);

    /** 物理层数据阻塞发送一个字节函数，有默认函数，用户也可以替换 */
    void (*tx_byte)(u32_t dev_ptr, u8_t c);

    /** 物理层数据阻塞发送函数，有默认函数，用户也可以替换 */
    void (*tx_bytes)(u32_t dev_ptr, u8_t *buf, u16_t len);

    /** 物理层有数据可接收函数，有默认函数，用户也可以替换，返回值为1则有数据可接收，0则无数据 */
    u8_t (*rx_available)(u32_t dev_ptr);

    /** 物理层有帧错误，有默认函数，用户也可以替换，返回值为1则帧错误，0则无帧错误 */
    u8_t (*rx_fe)(u32_t dev_ptr);

    /** 物理层数据非阻塞接收一个字节函数，有默认函数，用户也可以替换，返回值为1则收到数据，0则无数据 */
    u8_t (*rx_byte)(u32_t dev_ptr, u8_t *c);

    /** 物理层数据阻塞接收函数，有默认函数，用户也可以替换，返回值为接收到的数据 */
    u16_t (*rx_bytes)(u32_t dev_ptr, u8_t *buf, u16_t len, u32_t timeout);

    /** 物理层接收中断服务函数，有默认函数，用户也可以替换 */
    void (*rx_isr)(u32_t dev_ptr);

    /** 物理层清除FIFO函数，有默认函数，用户也可以替换 */
    void (*fifo_clear)(u32_t dev_ptr);

} UFCS_PHY_INFO_t;

#define N_MSG_NUMBER_COUNT      (15)    /* 消息编号计数阈值 */
#define N_MSG_RETRY_COUNT       (3)     /* 消息重发计数阈值 */

/* 协议层发送状态枚举类型 */
enum UFCS_PRL_TX_STATE_e
{
    UFCS_PRL_TX_RESET,                  /* 发送复位 */
    UFCS_PRL_TX_PREPARE,                /* 发送准备 */
    UFCS_PRL_TX_SEND_MSG,               /* 发送消息：消息封装与发送 */
    UFCS_PRL_TX_WAIT_RESP,              /* 发送等待回应 */
    UFCS_PRL_TX_REPORT_SUCCESS,         /* 发送成功 */
    UFCS_PRL_TX_CHECK_RETRY_CNT,        /* 重发次数检测 */
    UFCS_PRL_TX_REPORT_ERR,             /* 发送失败 */
};

/* 协议层接收状态枚举类型 */
enum UFCS_PRL_RX_STATE_e
{
    UFCS_PRL_RX_WAIT_MSG,               /* 等待接收消息 */
    UFCS_PRL_RX_CHECK_CRC,              /* CRC校验 */
    UFCS_PRL_RX_SEND_ACK,               /* 发送ACK消息 */
    UFCS_PRL_RX_REPORT_MSG,             /* 上报消息给应用层 */
    UFCS_PRL_RX_SEND_NCK,               /* 发送NCK消息 */
};

/** 协议层消息枚举类型 */
enum UFCS_PRL_MSG_TYPE_e
{
    UFCS_PRL_MSG_PING,
    UFCS_PRL_MSG_ACK,
    UFCS_PRL_MSG_NCK,
    UFCS_PRL_MSG_ACCEPT,
    UFCS_PRL_MSG_SOFT_RESET,
    UFCS_PRL_MSG_POWER_READY,
    UFCS_PRL_MSG_GET_OUTPUT_CAP,
    UFCS_PRL_MSG_GET_SRC_INFO,
    UFCS_PRL_MSG_GET_SNK_INFO,
    UFCS_PRL_MSG_GET_CBL_INFO,
    UFCS_PRL_MSG_GET_DEV_INFO,
    UFCS_PRL_MSG_GET_ERR_INFO,
    UFCS_PRL_MSG_DET_CBL_INFO,
    UFCS_PRL_MSG_START_CBL_DET,
    UFCS_PRL_MSG_END_CBL_DET,
    UFCS_PRL_MSG_EXIT_UFCS_MODE,

    UFCS_PRL_MSG_OUTPUT_CAP,
    UFCS_PRL_MSG_REQUEST,
    UFCS_PRL_MSG_SRC_INFO,
    UFCS_PRL_MSG_SNK_INFO,
    UFCS_PRL_MSG_CBL_INFO,
    UFCS_PRL_MSG_DEV_INFO,
    UFCS_PRL_MSG_ERR_INFO,
    UFCS_PRL_MSG_CFG_WDT,
    UFCS_PRL_MSG_REFUSE,
    UFCS_PRL_MSG_VERIFY_REQ,
    UFCS_PRL_MSG_VERIFY_RESP,
    UFCS_PRL_MSG_POWER_CHANGE,
    UFCS_PRL_MSG_TEST_REQ,

    UFCS_PRL_MSG_CUSTOM,

    UFCS_PRL_MSG_END
};

/* 协议消息方向 */
typedef enum UFCS_PRL_DIR_TYPE_e
{
    UFCS_PRL_RX,
    UFCS_PRL_TX,
    UFCS_PRL_DIR_END
} UFCS_PRL_DIR_TYPE_t;

/* 协议层状态结构定义 */
typedef struct UFCS_PRL_INFO_s
{
    u32_t rx_state:4,                   /* 接收状态 */
          rx_state_prev:4,              /* 前一次的接收状态 */

          rx_msg_id:4,                  /* 接收消息编号 */
          tx_state:4,                   /* 发送状态 */

          tx_state_prev:4,              /* 前一次的接收状态 */
          tx_msg_id:4,                  /* 发送消息编号 */

          rx_msg_ind:1,                 /* 接收消息指示，供策略控制引擎使用 */
          tx_msg_err:1,                 /* 消息发送错误，供策略控制引擎使用 */
          tx_msg2cbl_err:1,             /* 消息发送到线缆错误，供策略控制引擎使用 */
          tx_msg_sent_ind:1,            /* 消息发送已发送指示，供策略控制引擎使用 */
          reset:1,                      /* 协议层复位指示 */
          reset_complete:1,             /* 协议层复位完成 */
          hard_reset_sig_frm_phy:1,     /* 接收到物理层的硬件复位信号 */
          cable_reset_sig_frm_phy:1;    /* 接收到物理层的线缆复位信号 */

    u32_t tx_msg_type:8,                /* 发送消息类型，参考enum UFCS_PRL_MSG_TYPE_e  */
          rx_msg_type:8,                /* 接收消息类型，参考enum UFCS_PRL_MSG_TYPE_e */

          rx_msg_id_stored:1,           /* 接收消息编号存储标志 */
          tx_msg_req_frm_pe:1,          /* 来自策略控制引擎的发送消息请求 */
          tx_msg_in_prog:1,             /* 发送消息处理中标志 */
          hard_reset_ind:1,             /* 硬件复位状态指示标志 */
          exit_from_hard_reset:1,       /* 退出硬件复位状态 */
          hard_reset_sent:1,            /* 硬件复位信号已发送 */
          hr_cbl_rst_ind:1,             /* 线缆复位信号指示标志 */
          hrst_req_frm_pe:1,            /* 来自策略控制引擎的硬件复位请求 */

          hrst_cmplt_frm_pe:1,          /* 来自策略控制引擎的硬件复位完成 */
          cbl_rst_req_frm_pe:1,         /* 来自策略控制引擎的线缆复位请求 */
          cbl_rst_cmplt_frm_pe:1,       /* 来自策略控制引擎的线缆复位完成 */
          pe_informed_cab_rst:1,        /* 线缆复位已通知策略控制 */
          pe_informed_hrst:1,           /* 硬件复位已通知策略控制 */
          reserved1:3;                  /* 保留 */

    u32_t tx_data_offset:8,             /* 当前发送数据的offset */
          rx_data_offset:8,             /* 当前接收到数据的offset */

          rx_training_valid:1,          /* 接收到正确的Training */
          rx_msg_complete:1,            /* 接收数据完成标志，协议层使用 */
          rx_msg_crc_valid:1,           /* 接收到正确CRC的消息 */
          rx_msg_from_cbl:1,            /* 接收的消息来自线缆 */
          tx_msg_to_cbl:1,              /* 发送数据到线缆 */
          tx_msg_complete:1,            /* 发送数据完成标志，协议层使用 */
          tx_msg_retry_cnt:2,           /* 发送数据重试次数 */

          tx_phy_occupied:1,            /* 发送PHY占用标志，协议层使用 */
          rx_resp_sent:1,               /* 接收数据的ACK消息已发送，协议层使用 */
          reserved2:6;                  /* 保留 */

    u8_t rx_data[UFCS_MSG_MAX_SZ];      /* 接收缓冲区 */
    u8_t tx_data[UFCS_MSG_MAX_SZ];      /* 发送缓冲区 */
    UFCS_MSG_HEAD_t rx_head;            /* 接收消息头 */
    UFCS_MSG_HEAD_t tx_head;            /* 发送消息头 */
    u8_t rx_resp[UFCS_MSG_HEAD_SZ+UFCS_MSG_CMD_SZ+UFCS_MSG_CRC_SZ];    /* 接收数据的ACK消息 */

    u8_t training_code;                 /* training code */
    u8_t tx_temp_byte;                  /* 要发送的临时字节 */
    u8_t rx_training_code;              /* 接收到的training code */
    u8_t rx_last_byte;                  /* 接收到最后的一个字节数据 */
                           
    sys_tick_t rx_low_det_start;        /* 接收低电平检测开始时间 */

    drv_timer_t ACKReceiveTimer;        /* ACK接收定时器 */
    drv_timer_t MsgTransDelayTimer;     /* 消息传输延时定时器 */

} UFCS_PRL_INFO_t;

/* 策略控制状态枚举类型 */
enum UFCS_PE_STATE_e
{
    UFCS_PE_UNIDENTIFIED,               /* 未识别状态 */
    UFCS_PE_EXIT,                       /* 设备退出UFCS模式 */
    UFCS_PE_SEND_SOFT_RESET,            /* 设备发送软件复位 */
    UFCS_PE_SOFT_RESET,                 /* 设备软件复位 */
    UFCS_PE_HARD_RESET,                 /* 设备硬件复位 */
    UFCS_PE_VERIFY_REQ,                 /* 设备鉴权请求 */
    UFCS_PE_VERIFY_RESP,                /* 设备鉴权回应 */
    UFCS_PE_SEND_REFUSE,                /* 设备发送反馈信息 */

    UFCS_PE_SRC_DCP_DET1,               /* 供电设备检测脉冲序列tDet1 */
    UFCS_PE_SRC_DCP_DET2,               /* 供电设备检测脉冲序列tDet2 */
    UFCS_PE_SRC_DCP_DET3,               /* 供电设备检测脉冲序列tDet3 */
    UFCS_PE_SRC_DCP_DET4,               /* 供电设备检测脉冲序列tDet4 */
    UFCS_PE_SRC_HANDSHAKED,             /* 供电设备握手成功 */
    UFCS_PE_SRC_IDENTIFIED,             /* 供电设备UFCS识别成功 */
    UFCS_PE_SRC_SEND_OUTPUT_CAP,        /* 供电设备发送输出模式 */
    UFCS_PE_SRC_START_CBL_DET_RECEIVED, /* 供电设备接收到开始线缆检测消息 */
    UFCS_PE_SRC_END_CBL_DET_RECEIVED,   /* 供电设备接收到结束线缆检测消息 */
    UFCS_PE_SRC_DET_CBL_INFO_RECEIVED,  /* 供电设备接收到检测线缆信息消息 */
    UFCS_PE_SRC_START_CBL_DET,          /* 供电设备开始线缆检测 */
    UFCS_PE_SRC_GET_CBL_INFO,           /* 供电设备获取线缆信息 */
    UFCS_PE_SRC_END_CBL_DET,            /* 供电设备结束线缆检测 */
    UFCS_PE_SRC_NEGO_OUTPUT_CAP,        /* 供电设备协商输出能力 */
    UFCS_PE_SRC_OUTPUT_REFUSE,          /* 供电设备输出能力反馈 */
    UFCS_PE_SRC_TRANSIT_SUPPLY,         /* 供电设备切换输出能力 */
    UFCS_PE_SRC_PS_READY,               /* 供电设备电源输出准备好了 */
    UFCS_PE_SRC_GIVE_SRC_INFO,          /* 供电设备给出供电信息 */
    UFCS_PE_SRC_GIVE_DEV_INFO,          /* 供电设备给出设备信息 */
    UFCS_PE_SRC_GIVE_ERR_INFO,          /* 供电设备给出错误信息 */
    UFCS_PE_SRC_GET_SNK_INFO,           /* 供电设备获取供电信息 */
    UFCS_PE_SRC_GET_DEV_INFO,           /* 供电设备获取设备信息 */
    UFCS_PE_SRC_GET_ERR_INFO,           /* 供电设备获取错误信息 */

    UFCS_PE_SNK_VBUS_DET,               /* 充电设备检测VBUS是否有电压 */
    UFCS_PE_SNK_DCP_DET1,               /* 充电设备检测到BC1.2 DCP特性并发送脉冲序列tDet1 */
    UFCS_PE_SNK_DCP_DET2,               /* 充电设备发送脉冲序列tDet2 */
    UFCS_PE_SNK_DCP_DET3,               /* 充电设备发送脉冲序列tDet3 */
    UFCS_PE_SNK_DCP_DET4,               /* 充电设备发送脉冲序列tDet4 */
    UFCS_PE_SNK_DP_HIGH_DET,            /* 充电设备启动对 D+信号高电平检测 */
    UFCS_PE_SNK_DET_RETRY,              /* 充电设备握手失败后，重新启动握手检测 */
    UFCS_PE_SNK_SEND_PING,              /* 充电设备握手成功后，发送PING消息 */
    UFCS_PE_SNK_IDENTIFIED,             /* 充电设备UFCS识别成功 */
    UFCS_PE_SNK_GET_OUTPUT_CAP,         /* 充电设备发送获取输出模式消息 */
    UFCS_PE_SNK_START_CBL_DET,          /* 充电设备开始线缆检测 */
    UFCS_PE_SNK_GET_CBL_INFO,           /* 充电设备获取线缆信息 */
    UFCS_PE_SNK_END_CBL_DET,            /* 充电设备结束线缆检测 */
    UFCS_PE_SNK_START_CBL_DET_RECEIVED, /* 充电设备接收到开始线缆检测消息 */
    UFCS_PE_SNK_END_CBL_DET_RECEIVED,   /* 充电设备接收到结束线缆检测消息 */
    UFCS_PE_SNK_DET_CBL_INFO_RECEIVED,  /* 充电设备接收到检测线缆信息消息 */
    UFCS_PE_SNK_OUTPUT_REQ,             /* 充电设备输出能力请求 */
    UFCS_PE_SNK_TRANSIT_SNK,            /* 充电设备切换充电能力 */
    UFCS_PE_SNK_PS_READY,               /* 充电设备充电电源准备好了 */
    UFCS_PE_SNK_GIVE_SNK_INFO,          /* 充电设备给出充电信息 */
    UFCS_PE_SNK_GIVE_DEV_INFO,          /* 充电设备给出设备信息 */
    UFCS_PE_SNK_GIVE_ERR_INFO,          /* 充电设备给出错误信息 */
    UFCS_PE_SNK_GET_SRC_INFO,           /* 充电设备获取充电信息 */
    UFCS_PE_SNK_GET_DEV_INFO,           /* 充电设备获取设备信息 */
    UFCS_PE_SNK_GET_ERR_INFO,           /* 充电设备获取错误信息 */
    UFCS_PE_SNK_CFG_WDT,                /* 充电设备配置看门狗 */

    UFCS_PE_CBL_READY,                  /* 线缆开始上报线缆信息 */
    UFCS_PE_CBL_GET_CBL_INFO_RECEIVED,  /* 线缆接收到获取线缆信息 */
    UFCS_PE_CBL_SEND_CBL_INFO,          /* 线缆发送线缆信息 */
    UFCS_PE_CBL_HARD_RESET,             /* 线缆收到硬件复位 */
};

/* 策略控制引擎结构定义 */
typedef struct UFCS_PE_INFO_s
{
    u32_t state:8,                      /* 当前状态，参考enum UFCS_STATE_e */
          state_prev:8,                 /* 前一状态，参考enum UFCS_STATE_e */
          reserved1:16;                 /* 保留 */

    u32_t vbus_present:1,               /* VBUS存在标志 */
          sinking_vbus:1,               /* VBUS充电中 */
          sourcing_vbus:1,              /* VBUS供电中 */
          cableplug_detected:1,         /* 检测到线缆电子标签 */
          charger_cc:1,                 /* 供电设备处于恒流模式 */
          charger_cv:1,                 /* 供电设备处于恒压模式 */
          identified:1,                 /* 已识别标志 */
          soft_reset_req:1,             /* 请求软件复位，上层软件设置1 */

          hard_reset_req:1,             /* 请求硬件复位，上层软件设置1 */
          cable_reset_req:1,            /* 请求线缆硬件复位，上层软件设置1 */
          get_output_cap_req:1,         /* 请求获取输出模式，上层软件设置1 */
          get_src_info_req:1,           /* 请求获取供电信息，上层软件设置1 */
          get_snk_info_req:1,           /* 请求获取充电信息，上层软件设置1 */
          get_cbl_info_req:1,           /* 请求获取线缆信息，上层软件设置1 */
          get_dev_info_req:1,           /* 请求获取设备信息，上层软件设置1 */
          get_err_info_req:1,           /* 请求获取错误信息，上层软件设置1 */

          det_cbl_info_req:1,           /* 请求检测线缆信息，上层软件设置1 */
          start_cbl_det_req:1,          /* 请求开启线缆检测，上层软件设置1 */
          end_cbl_det_req:1,            /* 请求结束线缆检测，上层软件设置1 */
          exit_ufcs_mode_req:1,         /* 请求退出UFCS模式，上层软件设置1 */
          verify_req:1,                 /* 请求鉴权，上层软件设置1 */
          power_change_req:1,           /* 请求电源调整，上层软件设置1 */
          cfg_wdt_req:1,                /* 请求配置watchdog，上层软件设置1 */
          ping_req:1,                   /* 请求发送ping消息 */

          test_req:1,                   /* 请求启动测试，测试设备设置1 */
          identify_det_cnt:2,           /* 识别检测计数器 */
          ping_send_cnt:2,              /* 识别检测PING发送计数器 */
          get_output_cap_cnt:2,         /* 获取输出能力计数次 */
          reserved2:1;                  /* 保留 */
    
    u32_t obj_pos:4,                    /* 当前工作输出模式位置，1~7 */
          output_cap_mismatch:1,        /* 输出模式不匹配 */
          request_can_be_met:1,         /* 请求的输出模式能接受 */
          request_cant_be_met:1,        /* 请求的输出模式不能接受 */
          power_supply_ready:1,         /* 电源供电准备好了 */
          
          rx_output_num:4,              /* 接收到的输出模式数量 */
          rx_output_max_power_index:4,  /* 接收到的输出模式最大功率索引 */

          unexpected_msg_received:1,    /* 接收到不期望的消息 */
          unsupported_msg_received:1,   /* 接收到不支持的消息 */
          unrecognized_msg_received:1,  /* 接收到不识别的消息 */
          interruptible_AMS_entered:1,  /* 进入可打断的AMS操作 */
          non_interruptible_AMS_entered:1,  /* 进入不可打断的AMS操作 */
          hrst_in_prog:1,               /* 硬件复位正在操作中 */
          hrst_sig_frm_phy:1,           /* 接收到从PHY来的硬件复位信号 */
          cable_rst_in_prog:1,          /* 接收到从PHY来的线缆复位信号 */

          reserved3:8;                  /* 保留 */

    u32_t partner_opr_curr:16,          /* 对端设备的当前工作电流，单位 mA */
          partner_opr_volt:16;          /* 对端设备的当前工作电压，单位 mV */

    u32_t opr_curr:16,                  /* 当前工作电流，单位 mA */
          opr_volt:16;                  /* 当前工作电压，单位 mV */

    u32_t req_curr:16,                  /* 请求的工作电流，单位 mA */
          req_volt:16;                  /* 请求的工作电压，单位 mV */

    u32_t rx_output_max_power;          /* 接收到的输出模式最大功率，单位 mW */

    u32_t dev_temperature:8,            /* 当前设备温度 */
          usb_temperature:8,            /* 当前USB接口温度 */
          partner_dev_temperature:8,    /* 对端设备的设备温度 */
          partner_usb_temperature:8;    /* 对端设备的USB接口温度 */

    u32_t cbl_max_curr:8,               /* 最大承载电流，单位 1A */
          cbl_max_volt:8,               /* 最大承载电压，单位 1V */
          cbl_impedance:16;             /* 线缆阻抗，单位 mOh */

    u32_t partner_fw_ver:16,            /* 对端设备的设备软件版本号 */
          partner_hw_ver:16;            /* 对端设备的设备硬件版本号 */

    UFCS_DATA_MSG_ERR_INFO_t err_info;  /* 异常信息标记 */
    UFCS_DATA_MSG_ERR_INFO_t partner_err_info;  /* 异常信息标记 */
    UFCS_DATA_MSG_CFG_WDT_t wdt;        /* 看门狗溢出时间 */
    UFCS_DATA_MSG_REFUSE_t refuse;      /* Refuse消息 */

    union {
        struct {
            UFCS_DATA_MSG_OUTPUT_CAP_t caps[UFCS_MAX_OUTPUT_CAP_NUM]; /* 接收到的输出模式 */
        } rx_output;

        UFCS_DATA_MSG_REQUEST_t rx_request; /* 接收到的请求消息 */
    } rx_pwr;

    union {
        UFCS_DATA_MSG_POWER_CHANGE_t change;
        u8_t u8dat[3];
    } power_change[UFCS_MAX_OUTPUT_CAP_NUM+1];    /* 调整功率 */

    drv_timer_t identify_timer;             /* 识别定时器 */
    drv_timer_t sender_response_timer;      /* 发送者接收回应定时器 */
    drv_timer_t power_supply_timer;         /* 电源供电定时器 */
    drv_timer_t cable_info_timer;           /* 线缆信息定时器 */
    drv_timer_t restart_trans_timer;        /* 重传定时器 */
    drv_timer_t cable_trans_timer;          /* 线缆重传定时器 */
    drv_timer_t wdt_timer;                  /* 消息看门狗定时器 */
    drv_timer_t src_output_disabled_timer;  /* 断开输出定时器 */

    sys_tick_t identified_time;             /* 已识别开始时间 */
    sys_tick_t no_identified_time;          /* 没有识别到信号开始时间 */
    sys_tick_t ps_ready_time;               /* 电源供电准备好开始时间 */

} UFCS_PE_INFO_t;

/** VBUS电压阈值百分比  */
#define UFCS_VBUS_VOLT_MIN_THR          (0.90)
#define UFCS_VBUS_VOLT_MAX_THR          (1.10)

/** VBUS UVP 阈值百分比  */
#define UFCS_VBUS_VOLT_DROP_MIN_THR     (0.85)

/** VBUS OVP 阈值百分比  */
#define UFCS_VBUS_VOLT_OVP_MAX_THR      (1.12)


#define UFCS_TEST_DATA_SIZE             (24)
typedef struct UFCS_TEST_DATA_s
{
    u32_t valid:1;
    u32_t len:7;
    u32_t reserved:24;
    u8_t test_data[UFCS_TEST_DATA_SIZE];
} UFCS_TEST_DATA_t;

/**
 * UFCS 设备定义
 */
typedef struct UFCS_DEV_s {

	UFCS_DEV_CFG_t *cfg;                    /* 设备配置 指针 */
    UFCS_PHY_INFO_t phy;                    /* 物理层信息结构体 */
	UFCS_PRL_INFO_t prl;                    /* 协议层信息结构体 */
	UFCS_PE_INFO_t pe;                      /* 策略控制引擎结构体 */

    /** 设备未识别事件函数 */
    void (*unidentified)(u32_t dev_ptr);

    /** 设备已识别事件函数 */
    void (*identified)(u32_t dev_ptr);

    /** 检测到硬件复位回调函数 */
    void (*hard_reset_detected)(u32_t dev_ptr);

    /** 硬件复位完成回调函数 */
    void (*hard_reset_completed)(u32_t dev_ptr);

    /** 设备切换到新的电源函数 */
    status_t (*transit_to_new_power)(u32_t dev_ptr, u32_t pos);

    /** VBUS泄放设置函数 */
    void (*vbus_discharge_set)(u32_t dev_ptr, bool_t en);

    /** VBUS泄放状态获取函数 */
    bool_t (*vbus_discharge_get)(u32_t dev_ptr);

    /** VBUS电压获取函数 */
    u32_t (*vbus_volt_get)(u32_t dev_ptr);

    /** IBUS电流获取函数 */
    u32_t (*ibus_current_get)(u32_t dev_ptr);

    /** 电源改变请求回调函数 */
    void (*power_change_req)(u32_t dev_ptr);

    /** 鉴权请求回调函数 */
    void (*verify_req)(u32_t dev_ptr);

    /** 鉴权回应回调函数 */
    void (*verify_resp)(u32_t dev_ptr);

    /** UFCS空闲循环回调函数 */
    void (*idle_loop_hook)(u32_t dev_ptr);

    /** 协议层消息接收回调函数 */
    void (*prl_msg_received)(u32_t dev_ptr);

    /** 协议层消息发送回调函数 */
    void (*prl_msg_sent)(u32_t dev_ptr);

    /** 输出模式消息处理回调函数 */
    void (*msg_output_cap)(u32_t dev_ptr, UFCS_PRL_DIR_TYPE_t dir);

    /** 请求消息处理回调函数 */
    void (*msg_request)(u32_t dev_ptr, UFCS_PRL_DIR_TYPE_t dir);

} UFCS_DEV_t;


#pragma pack()

#endif /* #ifndef __UFCS_DEFS_H_ */

