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

#include "arch.h"
#include "types.h"

#pragma pack(1)

#define UFCS_TRAINING_CODE          (0xAA)

#define UFCS_MSG_HEAD_OFFSET        (0)
#define UFCS_MSG_HEAD_SZ            (2)
#define UFCS_MSG_MAX_SZ             (64)

#define UFCS_MSG_CMD_OFFSET         (UFCS_MSG_HEAD_OFFSET+UFCS_MSG_HEAD_SZ)
#define UFCS_MSG_CMD_SZ             (1)

#define UFCS_MSG_DATA_LEN_OFFSET    (UFCS_MSG_CMD_OFFSET+UFCS_MSG_CMD_SZ)
#define UFCS_MSG_DATA_LEN_SZ        (1)

#define UFCS_MSG_DATA_OFFSET        (UFCS_MSG_DATA_LEN_OFFSET+UFCS_MSG_DATA_LEN_SZ)

#define UFCS_MSG_CUST_RESV_SZ       (2)

#define UFCS_MSG_CRC_SZ             (1)


/* 消息类型 */
typedef enum UFCS_MSG_TYPE_e
{
    UFCS_MSG_TYPE_CTRL          = 0x00, /* 控制消息 */
    UFCS_MSG_TYPE_DATA          = 0x01, /* 数据消息 */
    UFCS_MSG_TYPE_USER_DEF      = 0x02, /* 自定义消息 */
    UFCS_MSG_TYPE_END
} UFCS_MSG_TYPE_t;

/* 设备定义 */
typedef enum UFCS_DEV_TYPE_e
{
    UFCS_DEV_TYPE_SRC           = 0x01, /* 供电设备 */
    UFCS_DEV_TYPE_SNK           = 0x02, /* 充电设备 */
    UFCS_DEV_TYPE_CBL           = 0x03, /* 线缆电子标签 */
    UFCS_DEV_TYPE_END
} UFCS_DEV_TYPE_t;

/* 消息头定义 */
typedef struct UFCS_MSG_HEAD_s 
{
    u16_t msg_type:3,           /* 消息类型 */
          spec_rev:6,           /* 协议版本编号 */
          msg_id:4,             /* 消息编号 */
          dev_type:3;           /* 设备类型 */
} UFCS_MSG_HEAD_t;

/* 控制命令定义 */
typedef enum UFCS_CTRL_MSG_CMD_e
{                                        /* 发送者                          接收者 */
    UFCS_CTRL_MSG_PING           = 0x00, /* 供电设备/充电设备               供电设备/充电设备/线缆电子标签 */
    UFCS_CTRL_MSG_ACK            = 0x01, /* 供电设备/充电设备/线缆电子标签  供电设备/充电设备/线缆电子标签 */
    UFCS_CTRL_MSG_NCK            = 0x02, /* 供电设备/充电设备/线缆电子标签  供电设备/充电设备/线缆电子标签 */
    UFCS_CTRL_MSG_ACCEPT         = 0x03, /* 供电设备/充电设备               供电设备/充电设备 */
    UFCS_CTRL_MSG_SOFT_RESET     = 0x04, /* 供电设备/充电设备               供电设备/充电设备/线缆电子标签 */
    UFCS_CTRL_MSG_POWER_READY    = 0x05, /* 供电设备                        充电设备 */
    UFCS_CTRL_MSG_GET_OUTPUT_CAP = 0x06, /* 充电设备                        供电设备 */
    UFCS_CTRL_MSG_GET_SRC_INFO   = 0x07, /* 充电设备                        供电设备 */
    UFCS_CTRL_MSG_GET_SNK_INFO   = 0x08, /* 供电设备                        充电设备 */
    UFCS_CTRL_MSG_GET_CBL_INFO   = 0x09, /* 供电设备/充电设备               线缆电子标签 */
    UFCS_CTRL_MSG_GET_DEV_INFO   = 0x0A, /* 供电设备/充电设备               供电设备/充电设备 */
    UFCS_CTRL_MSG_GET_ERR_INFO   = 0x0B, /* 供电设备/充电设备               供电设备/充电设备 */
    UFCS_CTRL_MSG_DET_CBL_INFO   = 0x0C, /* 供电设备/充电设备               充电设备/供电设备 */
    UFCS_CTRL_MSG_START_CBL_DET  = 0x0D, /* 供电设备/充电设备               充电设备/供电设备 */
    UFCS_CTRL_MSG_END_CBL_DET    = 0x0E, /* 供电设备/充电设备               充电设备/供电设备 */
    UFCS_CTRL_MSG_EXIT_UFCS_MODE = 0x0F, /* 供电设备/充电设备               充电设备/供电设备 */
    UFCS_CTRL_MSG_END
} UFCS_CTRL_MSG_CMD_t;

/* 控制消息 */
typedef struct UFCS_CTRL_MSG_s 
{
    UFCS_MSG_HEAD_t head;       /* 消息头 */
    u8_t command;               /* 控制命令 */
    u8_t crc;                   /* CRC */
} UFCS_CTRL_MSG_t;

/* 数据消息命令定义 */
typedef enum UFCS_DATA_MSG_CMD_e
{                                        /* 发送者                          接收者 */
    UFCS_DATA_MSG_OUTPUT_CAP     = 0x01, /* 供电设备                        充电设备 */
    UFCS_DATA_MSG_REQUEST        = 0x02, /* 充电设备                        供电设备 */
    UFCS_DATA_MSG_SRC_INFO       = 0x03, /* 供电设备                        充电设备 */
    UFCS_DATA_MSG_SNK_INFO       = 0x04, /* 充电设备                        供电设备 */
    UFCS_DATA_MSG_CBL_INFO       = 0x05, /* 线缆电子标签/供电设备/充电设备  供电设备/充电设备 */
    UFCS_DATA_MSG_DEV_INFO       = 0x06, /* 供电设备/充电设备               供电设备/充电设备 */
    UFCS_DATA_MSG_ERR_INFO       = 0x07, /* 供电设备/充电设备               供电设备/充电设备 */
    UFCS_DATA_MSG_CFG_WDT        = 0x08, /* 充电设备                        供电设备 */
    UFCS_DATA_MSG_REFUSE         = 0x09, /* 供电设备/充电设备/线缆电子标签  供电设备/充电设备 */
    UFCS_DATA_MSG_VERIFY_REQ     = 0x0A, /* 供电设备/充电设备               线缆电子标签/供电设备/充电设备 */
    UFCS_DATA_MSG_VERIFY_RESP    = 0x0B, /* 线缆电子标签/供电设备/充电设备  供电设备/充电设备 */
    UFCS_DATA_MSG_POWER_CHANGE   = 0x0C, /* 供电设备                        充电设备 */
    UFCS_DATA_MSG_TEST_REQ       = 0x0F  /* 测试设备                        供电设备/充电设备/线缆电子标签 */
} UFCS_DATA_MSG_CMD_t;

/* 数据消息 */
typedef struct UFCS_DATA_MSG_s 
{
    UFCS_MSG_HEAD_t head;       /* 消息头 */
    u8_t command;               /* 命令 */
    u8_t data_len;              /* 数据长度 */
    u8_t *p_data_obj;           /* 数据 + CRC 指针 */
} UFCS_DATA_MSG_t;

/* 输出模式定义 */
typedef struct UFCS_DATA_MSG_OUTPUT_CAP_s
{
    u32_t min_curr:8,           /* 最小输出电流，单位 10mA */
          max_curr:16,          /* 最大输出电流，单位 10mA */
          min_volt_l:8;         /* 低字节最小输出电压，单位 10mV */
    u32_t min_volt_h:8,         /* 高字节最小输出电压，单位 10mV */
          max_volt:16,          /* 最大输出电压，单位 10mV */
          volt_step_type:1,     /* 电压调节最小步进: 0b：10mV, 1b：20mV */
          curr_step_type:3,     /* 电流调节最小步进：000b：10mA，001b：20mA，010b：30mA，011b：40mA，100b：50mA，其它：保留 */
          index:4;              /* 输出模式编号，起始为1，依次加1 */
} UFCS_DATA_MSG_OUTPUT_CAP_t;

/* 请求数据定义 */
typedef struct UFCS_DATA_MSG_REQUEST_s
{
    u32_t req_curr:16,          /* 请求输出电流，单位 10mA */
          req_volt:16;          /* 请求输出电压，单位 10mV */
    u32_t reserved:28,          /* 保留 */
          index:4;              /* 输出模式编号 */
} UFCS_DATA_MSG_REQUEST_t;

/* 供电设备状态信息定义 */
typedef struct UFCS_DATA_MSG_SRC_INFO_s
{
    u32_t output_curr:16,       /* 当前输出电流，单位 10mA */
          output_volt:16;       /* 当前输出电压，单位 10mV */
    u32_t usb_temp:8,          /* 当前供电设备 USB 接口温度，单位摄氏度，温度换算公式： T = （ bit39…bit32） - 50。 */
          dev_temp:8,           /* 当前供电设备内部温度，单位摄氏度，温度换算公式： T = （ bit47…bit40） - 50。 */
          reserved:16;           /* 保留 */
} UFCS_DATA_MSG_SRC_INFO_t;

/* 充电设备状态信息定义 */
typedef struct UFCS_DATA_MSG_SNK_INFO_s
{
    u32_t charge_curr:16,       /* 当前充电电流，单位 10mA */
          charge_volt:16;       /* 当前电池电压，单位 10mV */
    u32_t usb_temp:8,          /* 当前充电设备 USB 接口温度，单位摄氏度，温度换算公式： T = （ bit39…bit32） - 50。 */
          dev_temp:8,           /* 当前充电设备内部温度，单位摄氏度，温度换算公式： T = （ bit47…bit40） - 50。 */
          reserved:16;           /* 保留 */
} UFCS_DATA_MSG_SNK_INFO_t;

/* 线缆信息定义 */
typedef struct UFCS_DATA_MSG_CBL_INFO_s
{
    u32_t max_curr:8,           /* 最大承载电流，单位 1A */
          max_volt:8,           /* 最大承载电压，单位 1V */
          impedance:16;         /* 线缆阻抗，单位 mOh */
    u32_t reserved1:16,         /* 保留位，默认值 0x0000 */
          reserved2:16;         /* 保留位，默认值 0x0000 */
} UFCS_DATA_MSG_CBL_INFO_t;

/* 设备信息定义 */
typedef struct UFCS_DATA_MSG_DEV_INFO_s
{
    u32_t fw_ver:16,            /* 设备软件版本号 */
          hw_ver:16;            /* 设备硬件版本号 */
    u32_t reserved1:16,         /* 保留位，默认值 0x0000 */
          reserved2:16;         /* 保留位，默认值 0x0000 */
} UFCS_DATA_MSG_DEV_INFO_t;

/* 异常信息定义 */
typedef struct UFCS_DATA_MSG_ERR_INFO_s
{
    u32_t ovp:1,                /* 0：正常； 1：输出 OVP */
          uvp:1,                /* 0：正常； 1：输出 UVP */
          ocp:1,                /* 0：正常； 1：输出 OCP */
          scp:1,                /* 0：正常； 1：输出 SCP */
          usb_otp:1,            /* 0：正常； 1： USB 接口 OTP */
          dev_bat_otp:1,        /* 0：正常； 1：设备内部/电池 OTP */
          cc_ovp:1,             /* 0：正常； 1： CCOVP */
          dm_ovp:1,             /* 0：正常； 1： D-OVP */
          dp_ovp:1,             /* 0：正常； 1： D+OVP */
          in_ovp:1,             /* 0：正常； 1：输入 OVP */
          in_uvp:1,             /* 0：正常； 1：输入 UVP */
          over_leakage:1,       /* 0：正常； 1：漏电流超标 */
          vbus_lost:1,          /* 0：正常； 1：输入掉电 */
          crc:1,                /* 0：正常； 1： CRC 异常导致关闭输出 */
          wdt:1,                /* 0：正常； 1：看门狗溢出 */
          reserved:17;          /* 保留 */
} UFCS_DATA_MSG_ERR_INFO_t;

/* 配置信息定义 */
typedef struct UFCS_DATA_MSG_CFG_WDT_s
{
    u16_t wdt_timeout;          /* 看门狗定时器溢出时间，单位 ms */
} UFCS_DATA_MSG_CFG_WDT_t;

/* 反馈信息拒绝原因定义 */
typedef enum UFCS_REFUSE_REASON_e
{
    UFCS_REFUSE_REASON_RESERVED, 
    UFCS_REFUSE_REASON_UNRECOGNIZED_MSG = 0x01, /* 无法识别的命令或数据 */
    UFCS_REFUSE_REASON_UNSUPPORTED_MSG  = 0x02, /* 不支持的命令或数据 */
    UFCS_REFUSE_REASON_BUSY             = 0x03, /* 设备忙，暂无法响应 */
    UFCS_REFUSE_REASON_OUT_OF_RANGE     = 0x04, /* 充电设备请求的输出电压、电流或功率超出范围 */
    UFCS_REFUSE_REASON_OTHER            = 0x05  /* 其它原因 */
} UFCS_REFUSE_REASON_t;

/* 反馈信息定义 */
typedef struct UFCS_DATA_MSG_REFUSE_s
{
    u32_t reason:8,             /* 拒绝原因：0x01 -> 无法识别的命令或数据 0x02 -> 不支持的命令或数据 0x03 -> 设备忙，暂无法响应 0x04 -> 充电设备请求的输出电压、电流或功率超出范围 0x05 -> 其它原因 */
          command:8,            /* 命令编号，Refuse 消息所拒绝的消息的命令编号，如果拒绝的是厂家自定义消息，无法识别的话，该字段填 0x00 */
          msg_type:3,           /* 消息类型： Refuse 消息所拒绝的消息的消息类型 */
          reserved1:5,          /* 保留 */
          msg_id:4,             /* 消息编号： Refuse 消息所拒绝的消息的消息编号 */
          reserved2:4;          /* 保留 */
} UFCS_DATA_MSG_REFUSE_t;

/* 鉴权请求定义 */
typedef struct UFCS_DATA_MSG_VERIFY_REQ_s
{
    u8_t key_index;             /* 密钥编号 */
    u8_t random_data[16];       /* 随机数据 */
} UFCS_DATA_MSG_VERIFY_REQ_t;

/* 鉴权回应定义 */
typedef struct UFCS_DATA_MSG_VERIFY_RESP_s
{
    u8_t secure_data[32];       /* 加密数据 */
    u8_t random_data[16];       /* 随机数据 */
} UFCS_DATA_MSG_VERIFY_RESP_t;

/* 电源改变消息定义 */
typedef struct UFCS_DATA_MSG_POWER_CHANGE_s
{
    u16_t max_curr;             /* 最大输出电流，单位 10mA */
    u8_t  reserved:4,           /* 保留 */
          index:4;              /* 输出模式编号 */
} UFCS_DATA_MSG_POWER_CHANGE_t;

/* 厂商自定义消息 */
typedef struct UFCS_CUSTOM_MSG_s 
{
    UFCS_MSG_HEAD_t head;       /* 消息头 */
    u16_t reserved;             /* 保留位 */
    u8_t data_len;              /* 数据长度 */
    u8_t *p_data_obj;           /* 数据 + CRC 指针 */
} UFCS_CUSTOM_MSG_t;

#pragma pack()

#endif /* #ifndef __UFCS_MSG_DEFS_H_ */

