#include "MCU_Core_Protocol.h"
#include "Protocol_User.h"
#include "UART.h"

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

typedef struct
{
    Protocol_uint32_t read_pos;
    Protocol_uint32_t write_pos;
    Protocol_uint8_t  Rx_Buffer [ UART_RX_MAX_DEPTH ];
} UARTRxBuf_t;

typedef struct
{
    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 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 u32Len);
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)
{
    static Protocol_uint8_t DataBuf [ 256 ];
    Protocol_uint32_t i       = 0u;
    Protocol_uint32_t DataLen = 0u;
    Protocol_uint32_t SendLen = 0u;

    if ( UART_Ch1_Get_TX_Busy_Flag( ) == 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 > 64 )
        {
            SendLen = 64;
        }
        else
        {
            SendLen = DataLen;
        }

        for ( i = 0u; i < SendLen; i++ )
        {
            DataBuf [ i ]      = UARTTxBuf.Tx_Buffer [ UARTTxBuf.read_pos ];
            UARTTxBuf.read_pos = (UARTTxBuf.read_pos + 1) % UART_TX_MAX_DEPTH;
        }

        UART_Ch1_Send_Multiple_Byte(DataBuf, 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)
{
    
    if ( pData->CmdID == SOC_START_PROTOCOL_ID )
    {
        Core_Startup_Handle(pData->PowerSts);    //数据位使用不当，原电源位，现未使用，看情况是否更改
    }
    else if ( pData->CmdID == SOC_HEART_PROTOCOL_ID )
    {        
        Core_Heart_Handle(pData->Data, pData->DataLen);
    }
    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;
}
