#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "./hmi/hmi_hex_parse.h"
#include "./BSP/USART2/usart2.h"
#include "./SYSTEM/delay/delay.h"



/*
    举例数据帧格式（用户可以自行修改）：
        AA(1bytes 帧头) + FUNC(1bytes 功能字) + DATALEN(1bytes 数据长度) + DATA(数据) + TAIL(2bytes 帧尾)
  */

#define  HEAD       0xAA
#define  TAIL0      0xFE
#define  TAIL1      0xFE



enum rx_status
{
    WAIT_HEAD,
    WAIT_FUNC,
    WAIT_DATALEN,
    WAIT_DATA,
    WAIT_TAIL0,
    WAIT_TAIL1,
};

struct hmi_hex_parse
{
    enum rx_status status;

#define UART_PARSE_BUF_SIZE   (255)
    uint8_t rx_buf[UART_PARSE_BUF_SIZE];
    uint32_t rx_cnt;

    struct hex_cmd_fmt pack;
};

static struct hmi_hex_parse mgr;


/**
 * @brief   解析十六进制指令
 * @return  -1:未解析成功
 *          0:解析成功
 */
int hmi_hex_parse_byte_to_byte(uint8_t byte)
{
    int ret = -1;

    switch (mgr.status)
    {
    case WAIT_HEAD:
        if (byte == HEAD)
        {
            mgr.status = WAIT_FUNC;
            mgr.pack.head = byte;
        }
        break;

    case WAIT_FUNC:
        mgr.pack.func = byte;
        mgr.status = WAIT_DATALEN;
        break;

    case WAIT_DATALEN:
        mgr.pack.datalen = byte;
        mgr.status = WAIT_DATA;
        mgr.rx_cnt = 0;
        if (byte == 0)
        {
            mgr.status = WAIT_TAIL0;
        }
        else if (byte > UART_PARSE_BUF_SIZE)
        {
            mgr.status = WAIT_HEAD;
        }
        break;

    case WAIT_DATA:
        mgr.rx_buf[mgr.rx_cnt++] = byte;
        if (mgr.rx_cnt == mgr.pack.datalen)
        {
            mgr.status = WAIT_TAIL0;
        }
        break;

    case WAIT_TAIL0:
        mgr.pack.tail0 = byte;
        mgr.status = WAIT_TAIL1;
        if (byte != TAIL0)
        {
            mgr.status = WAIT_HEAD;
        }
        break;

    case WAIT_TAIL1:
        mgr.pack.tail1 = byte;
        mgr.status = WAIT_HEAD;
        if (byte == TAIL1)
        {
            mgr.pack.data = mgr.rx_buf;
            hmi_hex_cmd_parse(&mgr.pack); /*  解析成功，处理数据  */
            ret = 0;
        }
        break;
    }

    return ret;
}

void hmi_hex_parse_reest(void)
{
    mgr.status =  WAIT_HEAD;
}


/***************************************************************************/

enum hex_cmd_func
{
    FUNC_LED0_ON,
    FUNC_LED0_OFFF,
    FUNC_LED1_ON,
    FUNC_LED1_OFFF,
};

__weak void hmi_hex_cmd_parse(struct hex_cmd_fmt *fram)
{
    switch (fram->func)
    {
    case FUNC_LED0_OFFF:
        /*  用户补充自己的代码  */
        break;

    case FUNC_LED0_ON:
        /*  用户补充自己的代码  */
        break;

    case FUNC_LED1_OFFF:
        /*  用户补充自己的代码  */
        break;

    case FUNC_LED1_ON:
        /*  用户补充自己的代码  */
        break;
    }
}





