#include "Protocol_User.h"
#include "RTE.h"
#include "Components.h"

#define UART_TX_MAX_DEPTH 1024UL          //(2 * 1024UL)    // 4K
#define UART_RX_MAX_DEPTH (2 * 1024UL)    // 4K
#define UART_DATA_BUF_LEN (2 * 1024UL)    // 4K

typedef struct __attribute__((aligned(4)))
{
    Protocol_uint32_t read_pos;
    Protocol_uint32_t write_pos;
    Protocol_uint8_t  Rx_Buffer [ UART_RX_MAX_DEPTH ];
} UARTRxBuf_t;

typedef struct __attribute__((aligned(4)))
{
    Protocol_uint32_t read_pos;
    Protocol_uint32_t write_pos;
    Protocol_uint8_t  Tx_Buffer [ UART_TX_MAX_DEPTH ];
} UARTTxBuf_t;

static UARTRxBuf_t      UARTRxBuf;
static UARTTxBuf_t      UARTTxBuf;
static Protocol_uint8_t UsartDataBuf [ 256 ];
static Protocol_uint8_t mDataBufPtr [ UART_DATA_BUF_LEN ];

static Protocol_uint8_t  Protocol_OpenUart(void);
static Protocol_uint32_t Protocol_UartRead(Protocol_uint8_t *pData, Protocol_uint32_t len);
static Protocol_uint32_t Protocol_UartSend(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
static void              Protocol_UartHandle(const Protocol_Data_t *pData);

void Protocol_KL30_Wakeup_Init(void)
{
    Protocol_Func_t pFunc;

    pFunc.UARTOpen_Cbk        = Protocol_OpenUart;
    pFunc.UARTSend_Cbk        = Protocol_UartSend;
    pFunc.UARTRead_Cbk        = Protocol_UartRead;
    pFunc.UARTClose_Cbk       = Protocol_NULL;
    pFunc.ProcParseCbk        = Protocol_NULL;
    pFunc.ProtocolSetData_Cbk = Protocol_UartHandle;
    UARTTxBuf.read_pos        = 0;
    UARTTxBuf.write_pos       = 0;
    UARTRxBuf.read_pos        = 0;
    UARTRxBuf.write_pos       = 0;

    Protocol_Init(mDataBufPtr, UART_DATA_BUF_LEN, &pFunc);
}

void Protocol_Send_Service(void)
{
    Protocol_uint32_t i       = 0u;
    Protocol_uint32_t DataLen = 0u;
    Protocol_uint32_t SendLen = 0u;
   
    if ( UARTTxBuf.write_pos == UARTTxBuf.read_pos )
    {
        return;
    }
    if ( UARTTxBuf.write_pos > UARTTxBuf.read_pos )
    {
        DataLen = UARTTxBuf.write_pos - UARTTxBuf.read_pos;
    }
    else
    {
        DataLen = UART_TX_MAX_DEPTH - (UARTTxBuf.read_pos - UARTTxBuf.write_pos);
    }
    if ( DataLen > 255 )
    {
        SendLen = 255;
    }
    else
    {
        SendLen = DataLen;
    }
    for ( i = 0u; i < SendLen; i++ )
    {
        UsartDataBuf [ i ] = UARTTxBuf.Tx_Buffer [ UARTTxBuf.read_pos ];
        UARTTxBuf.read_pos = (UARTTxBuf.read_pos + 1) % UART_TX_MAX_DEPTH;
    }
    Uart0_IntSend(UsartDataBuf, SendLen);
        

   
}

static Protocol_uint8_t Protocol_OpenUart(void)
{
#if 0
    UART_Channel_Config_st_t loc_config;

    loc_config.u32UARTChEn            = 1;
    loc_config.u32UARTbps             = 115200;
    loc_config.pfnUARTConfirmCallBack = Protocol_NULL;
    loc_config.pfnUARTReadMsgCallBack = UART_Put;

    UART_Init(UART_RLIN31, &loc_config);
#endif
    return 1;
}

static Protocol_uint32_t Protocol_UartRead(Protocol_uint8_t *pData, Protocol_uint32_t len)
{
    Protocol_uint32_t i       = 0;
    Protocol_uint32_t DataLen = 0u;
    Protocol_uint32_t ReadLen = 0u;

    if ( UARTRxBuf.write_pos == UARTRxBuf.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf.write_pos > UARTRxBuf.read_pos )
    {
        DataLen = UARTRxBuf.write_pos - UARTRxBuf.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf.read_pos - UARTRxBuf.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf.Rx_Buffer [ UARTRxBuf.read_pos ];
        UARTRxBuf.read_pos = (UARTRxBuf.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return ReadLen;
}

static Protocol_uint32_t Protocol_UartSend(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len)
{
    Protocol_uint32_t i         = 0;
    Protocol_uint32_t RemainLen = 0u;

    if ( UARTTxBuf.write_pos >= UARTTxBuf.read_pos )
    {
        RemainLen = UART_TX_MAX_DEPTH - (UARTTxBuf.write_pos - UARTTxBuf.read_pos);
    }
    else
    {
        RemainLen = UARTTxBuf.read_pos - UARTTxBuf.write_pos;
    }

    if ( u32Len > RemainLen )
    {
        return 1;    //队列已满,无法插入队列
    }

    for ( i = 0; i < u32Len; i++ )
    {
        UARTTxBuf.Tx_Buffer [ UARTTxBuf.write_pos ] = pData [ i ];
        UARTTxBuf.write_pos                         = (UARTTxBuf.write_pos + 1) % UART_TX_MAX_DEPTH;
    }

    return 0;
}

static void Protocol_UartHandle(const Protocol_Data_t *pData)
{
    uint8_t ID04[1] = {0};
    if ( pData->CmdID == ESP32_MCU_0x10 )
    {       
        BlueTooth.BlueTooth_St = pData->Data[0];
        if (BlueTooth.BlueTooth_St == BLUE_STATE_ON)
        {
            Protocol_Send(MCU_ESP32_0x20, Protocol_NULL, 0);
        }
    }
    else if ( pData->CmdID == ESP32_MCU_0x12 )
    {
        BlueTooth.BLE_St = pData->Data[0];
    }
    else if ( pData->CmdID == ESP32_MCU_0x05 )
    {
        BlueTooth.ESP32_SWV = pData->Data[0];
    }
    else if ( pData->CmdID == ESP32_MCU_0x02 )
    {
        BlueTooth.ESP32_Reset = pData->Data[0];
        if (BlueTooth.ESP32_Reset == 1)
        {
            ID04[0] = 1;
            Protocol_Send(MCU_ESP32_0x04, ID04, 1);            
           
        }
        else if(BlueTooth.ESP32_Reset == 2)
        {
             __NVIC_SystemReset();
        }
        else
        {
            ;
        }
    }
    else if(pData->CmdID == ESP32_MCU_0x01 )
    {
       if (pData->Data[0] == 0x33)
        {
            BlueTooth.Navigation_St = EM_ESP32_NAVI_ST_NAVIGATING;
        }
        else if (pData->Data[0] == 0x35)
        {
            BlueTooth.Navigation_St = EM_ESP32_NAVI_ST_STANDBY;
        }
        else
        {
            ;
        }
        BlueTooth.Navigation_Code = pData->Data[1];
        BlueTooth.Navigation_Mileage = ((pData->Data[5] << 24) | (pData->Data[4] << 16) |
                                        (pData->Data[3] << 8) | pData->Data[2]);
    }    
    else
    {
        //非本协议数据,不处理
    }
}

void UART_Put(Protocol_uint16_t Data)
{
    Protocol_uint32_t nextPos = 0u;

    nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf.read_pos )
    {
        //队列已满,无法插入队列
    }
    else
    {
        UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Data;
        UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
    }

    //return;
}