#ifndef PROTOCOL_LIB_H
#define PROTOCOL_LIB_H

/*
Platform_32Bit
Platform_16Bit
*/
#ifdef Platform_16Bit
    #define Protocol_uint8_t  unsigned char
    #define Protocol_uint16_t unsigned int
    #define Protocol_uint32_t unsigned long
#else
    #define Protocol_uint8_t  unsigned char
    #define Protocol_uint16_t unsigned short
    #define Protocol_uint32_t unsigned int
    #define Protocol_uint64_t unsigned long long
#endif

#ifndef Protocol_NULL
    #define Protocol_NULL ( void * )0u
#endif /* NULL */

/**<0xEB 0x90 长度 帧序号 命令字 DATA0-DATAN CRC16_1 CRC16_2*/
#define DATA_PACKAGE_MIN_LEN   7 /**< 0xEB 0x90 + 长度 + 数据包序号 + CMDID + CRC16_1 + CRC16_2 */
#define DATA_PACKAGE_FIXED_LEN 3 /**< 未计算在长度内的数据  0xEB 0x90 + 长度位 */

#define CMD_HEAD1 0xEB
#define CMD_HEAD2 0x90

/**@struct   Protocol_Data_t
 * @brief    解析后的协议数据
 */
typedef struct
{
    Protocol_uint8_t FrameNo;      /**< 帧序号 */
    Protocol_uint8_t PowerSts;     /**< 电源状态 */
    Protocol_uint8_t CmdID;        /**< 命令字 */
    Protocol_uint8_t DataLen;      /**< 有效数据长度 DATA0-DATAN*/
    Protocol_uint8_t Data [ 256 ]; /**< 有效数据内容 DATA0-DATAN*/
} Protocol_Data_t;

typedef Protocol_uint8_t (*UARTOpen)(void);
typedef Protocol_uint32_t (*UARTSend)(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
typedef Protocol_uint32_t (*UARTRead)(Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
typedef void (*ProtocolSetData)(const Protocol_Data_t *pData);
typedef void (*ProcParse)(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
typedef void (*UARTClose)(void);

/**@struct   Protocol_Func_t
 * @brief    协议解析回调函数
 */
typedef struct
{
    UARTOpen        UARTOpen_Cbk;        /**< 串口打开回调 */
    UARTSend        UARTSend_Cbk;        /**< 串口发送回调 */
    UARTRead        UARTRead_Cbk;        /**< 串口读取回调 */
    UARTClose       UARTClose_Cbk;       /**< 串口关闭回调 */
    ProcParse       ProcParseCbk;        /**< 解析后的数据, 处理了数据包序号，命令字和电源状态，和ProcParse二选一 */
    ProtocolSetData ProtocolSetData_Cbk; /**< 不包含 0xEB 0x90 + 长度 + CRC16_1 + CRC16_2，和ProtocolSetData二选一 */
} Protocol_Func_t;

void              Protocol_Init(Protocol_uint8_t *pMemSpace, Protocol_uint32_t MemLen, Protocol_Func_t *pFunc);
void              Protocol_Service(void);
Protocol_uint32_t Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
Protocol_uint32_t Protocol_Send(const Protocol_uint16_t cmdID, const Protocol_uint8_t *pData, Protocol_uint8_t len);

#define UPGRADE_N32G031

#ifdef UPGRADE_N32G031
#define CMD_SET_BR          0x01//设置串口波特率
#define CMD_GET_INF         0x10//读取芯片型号索引、BOOT 版本号、芯片 ID
#define CMD_FLASH_ERASE     0x30//擦除 FLASH
#define CMD_FLASH_DWNLD     0x31//下载用户程序到 FLASH
#define CMD_DATA_CRC_CHECK  0x32//CRC 校验下载用户程
#define CMD_OPT_RW          0x40//读取/配置选项字节（包含了读保护等级、FLASH 页写保护、Data0/1 配置等）
#define CMD_SYS_RESET       0x50//系统复位
#define CMD_APP_GO          0x51//跳转到用户区执行程序
typedef struct 
{
    Protocol_uint8_t CMDH;  //宏定义所包含的
    Protocol_uint8_t CMDL;  
    Protocol_uint16_t LEN;  //不关心发送的端格式
    Protocol_uint8_t PAR[4];//需要处理好段格式
    Protocol_uint8_t DAT[160];//补充的数据直接补充好再传到下层
}UpdateProtocolStructure;//上层协议数据结构

typedef struct 
{	
 Protocol_uint8_t CMDH ;
 Protocol_uint8_t CMDL ;	
 Protocol_uint8_t LEN[2];
 union
 {
    Protocol_uint8_t DAT[128];
    struct 
    {
        Protocol_uint8_t unused_0   :8;
        Protocol_uint8_t BootVer    :8;
        Protocol_uint8_t BootCmdVer :8;
        Protocol_uint8_t UCID       [16];
        Protocol_uint8_t ChipID_UID [12];
        Protocol_uint8_t DBGMCU_IDCODE[4];
        Protocol_uint8_t Other      [16];
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }Chipinf;
    struct 
    {
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }Erase;
    struct 
    {
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }download;
    
    struct 
    {
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }verification;
    struct 
    {
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }reset;

    struct 
    {
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }appgo;
    struct 
    {
        struct Protocol_Lib
        {
            Protocol_uint8_t RDP ;
            Protocol_uint8_t nRDP ;
            Protocol_uint8_t USER ;
            Protocol_uint8_t nUSER ;
            Protocol_uint8_t Data0;
            Protocol_uint8_t nData0;
            Protocol_uint8_t Data1;
            Protocol_uint8_t nData1;
            Protocol_uint8_t WRP0;
            Protocol_uint8_t nWRP0;
            Protocol_uint8_t WRP1;
            Protocol_uint8_t nWRP1;
            Protocol_uint8_t RDP2;
            Protocol_uint8_t nRDP2;
            Protocol_uint8_t Reserved;
            Protocol_uint8_t nReserved;
        }optionbyte;
        Protocol_uint8_t CR1        :8;
        Protocol_uint8_t CR2        :8;
    }flashOpt;
    	
 }dat;	
 
}N32G031_ACK_Structure;//下层应答协议
extern N32G031_ACK_Structure N32G031_ACK;

Protocol_uint32_t UpdateN32G031Protocol_Send(UpdateProtocolStructure SendPd);
Protocol_uint32_t UpdateN32G031Protocol_Parse(const Protocol_uint8_t *pData, Protocol_uint32_t len);
#endif
#endif
