/*
 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
 */

/******************************************************************************
 * @file     sys_console.c
 * @brief    CSI Source File for console
 * @version  V1.0
 * @date     2019-12-19
 ******************************************************************************/

#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <drv/pin.h>
#include <string.h>
#include "console/sys_console.h"

extern csi_uart_t console_uart;
extern volatile unsigned char f_asr_response;

static volatile unsigned char uart_rx_async_flag = 0; //串口中断触发一次标志位，现在程序中当该标志位等于1，则表示接受到1byte数据
static volatile unsigned char uart_tx_async_flag = 0; //没用到

struct _uart0Buffer
{
    unsigned char writeIndex;          //接收串口数据写入缓存次数
    unsigned char readIndex;           //接收串口数据读取缓存次数
    volatile unsigned char new_packet; //缓存区还剩余串口数据条数
};
#define UART0_RCV_BUFFER_NUM 5       //接收串口命令缓存数量
#define UART0_RCV_BUFFER_PER_SIZE 32 //接收串口命令缓存长度
#define UART0_RCV_HEAD 0xBB          //接收串口命令数据头
#define UART0_RCV_END 0xBB           //接收串口命令数据尾
static unsigned char uartRcvBuffer[UART0_RCV_BUFFER_NUM][UART0_RCV_BUFFER_PER_SIZE];
static struct _uart0Buffer uartRcvBufferArry;

struct _uart0_rcv
{
    unsigned int cntEnd;
    unsigned int start;
    unsigned char dat[UART0_RCV_BUFFER_PER_SIZE]; //接收串口数据最大长度
} __attribute__((aligned(1)));
static struct _uart0_rcv uart_rcv;

int asr_rcv_write_cache_uart0(unsigned char *buf, unsigned int bufLen)
{
    if ((uartRcvBufferArry.new_packet + 1) == UART0_RCV_BUFFER_NUM)
    {
        return 0;
    }
    memcpy(&uartRcvBuffer[uartRcvBufferArry.writeIndex], buf, bufLen);
    uartRcvBuffer[uartRcvBufferArry.writeIndex][UART0_RCV_BUFFER_PER_SIZE - 1] = bufLen;
    uartRcvBufferArry.writeIndex++;
    uartRcvBufferArry.writeIndex %= UART0_RCV_BUFFER_NUM;
    uartRcvBufferArry.new_packet++;
    return 1;
}

unsigned char *asr_rcv_read_cache_uart0()
{
    if (uartRcvBufferArry.new_packet)
    {
        unsigned short index = uartRcvBufferArry.readIndex;
        uartRcvBufferArry.readIndex++;
        uartRcvBufferArry.readIndex %= UART0_RCV_BUFFER_NUM;
        uartRcvBufferArry.new_packet--;
        return (unsigned char *)uartRcvBuffer[index];
    }
    return 0;
}

/* uart0 开始接受数据 */
static void asr_rcv_log_uart_init()
{
    memset(uart_rcv.dat, 0, sizeof(uart_rcv.dat));
    uartRcvBufferArry.readIndex = 0;
    uartRcvBufferArry.writeIndex = 0;
    uartRcvBufferArry.new_packet = 0;
    /* UART以异步模式读取数据 详情见api */
    csi_uart_receive_async(&console_uart, uart_rcv.dat + uart_rcv.cntEnd, 1);
}
// 数据接收

void asr_rcv_log_uart_start(void)
{
    if (uart_rcv.dat[uart_rcv.cntEnd] == UART0_RCV_END && uart_rcv.start)
    {
        uart_rcv.start = 0;
        asr_rcv_write_cache_uart0(uart_rcv.dat, uart_rcv.cntEnd + 1);
        uart_rcv.cntEnd = 0;
        memset(uart_rcv.dat, 0, sizeof(uart_rcv.dat));
    }
    if (!uart_rcv.start)
    {
        if (uart_rcv.dat[uart_rcv.cntEnd] == UART0_RCV_HEAD)
        {
            uart_rcv.start = 1;
            uart_rcv.cntEnd++;
        }
    }
    else
    {
        uart_rcv.cntEnd++;
    }
    if (uart_rcv.cntEnd > sizeof(uart_rcv.dat))
    {
        uart_rcv.cntEnd = 0;
    }
    /* UART以异步模式读取数据 详情见api */
    csi_uart_receive_async(&console_uart, uart_rcv.dat + uart_rcv.cntEnd, 1);
	printf("uart rec %x\n",uart_rcv.dat[5]);
}
 
static void asr_rcv_log_event_cb(csi_uart_t *uart, csi_uart_event_t event, void *arg)
{
    switch (event)
    {
    case UART_EVENT_SEND_COMPLETE: //用不到
        break;

    case UART_EVENT_RECEIVE_COMPLETE:
        asr_rcv_log_uart_start();
        break;
    case UART_EVENT_RECEIVE_FIFO_READABLE: //用不到
        break;

    default:
        break;
    }
}

/**
  \brief       Get received data.
  \param[out]  The length of the received data.
  \return      Pointer to the rcvdata.hard = 0xAA，end = 0xBB
*/
unsigned char *asr_rcv_log_uart_data_get(unsigned char *bufLen)
{
    unsigned char *temPtr = NULL;
    //    if (!f_asr_response)
    //    {//注释掉这里主要是为了在播放提示音的时候uart0也能够透传
    temPtr = asr_rcv_read_cache_uart0();
    //   }
    if (temPtr)
    {
        *bufLen = temPtr[UART0_RCV_BUFFER_PER_SIZE - 1];
#if APP_LOG_ENABLE
        printf("\n-----------------------------------------------\n");
        printf("RcvMacDataBuf UART_0: 0x");
        unsigned int i = 0;
        for (i = 0; i < *bufLen; i++)
        {
            printf("%02X, ", temPtr[i]);
        }
        printf("\n-----------------------------------------------\n");
#endif
    }
    return (unsigned char *)temPtr;
}

int32_t console_init(sys_console_t *handle)
{
    int32_t ret = 0;

    /* 设置PIN的模式：上拉输入 */
    csi_pin_mode(handle->rx.pin, GPIO_MODE_PULLUP);

    /* 设置PIN的复用功能 */
    csi_pin_set_mux(handle->tx.pin, handle->tx.func);
    csi_pin_set_mux(handle->rx.pin, handle->rx.func);
    csi_pin_drive(handle->tx.pin, PIN_DRIVE_LV3);
    csi_pin_drive(handle->rx.pin, PIN_DRIVE_LV3);
    
    /* 通过设备号初始化对应的uart实例 */
    ret = csi_uart_init(&console_uart, handle->uart_id);

    /* config the UART */
    /* 设置波特率 */
    ret = csi_uart_baud(&console_uart, handle->baudrate);
    if (ret < 0)
    {
        return -1;
    }

    /*uart设备配置数据位，奇偶校验位和停止位，详情见pdf：api*/
    ret = csi_uart_format(&console_uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1);
    if (ret < 0)
    {
        return -1;
    }

    handle->uart = &console_uart; //没用，用不用管，留着，指向uart0句柄

    /*设置回调，不设置的话没法接收*/
    ret = csi_uart_attach_callback(&console_uart, asr_rcv_log_event_cb, NULL);
    if (ret != CSI_OK)
    {
        return -1;
    };

    asr_rcv_log_uart_init();
    return 0;
}
