#include <stdarg.h>
#include "../User/include/includes.h"

UART_t g_uart[UART_MAX];

uint8_t g_Dealbuf[USART_BUFFER_SIZE];
uint16_t g_DealLen = 0x00;

//uint8_t UART0_RecvBuff[USART_BUFFER_NUM][USART_BUFFER_SIZE];  //USART0 的数据接收缓存
//uint8_t *UART0_RecvInPtr;               //指向接收缓冲区存放数据的位置
//uint8_t *UART0_RecvOutPtr;              //指向接收缓冲区读取数据的位置
//uint8_t *UART0_RecvEndPtr;              //指向接收缓冲区结束的位置
//
////用于RS485发送
//uint8_t UART0_SendBuff[UART_SEND_BUFFER_NUM][UART_SEND_BUFFER_SIZE];  //USART0 的数据发送缓存
//uint8_t *UART0_SendInPtr;               //指向发送缓冲区存放数据的位置
//uint8_t *UART0_SendOutPtr;              //指向发送缓冲区读取数据的位置
//uint8_t *UART0_SendEndPtr;              //指向发送缓冲区结束的位置

/*********************************************************************
 * @fn      : UARTx_Init
 * @brief   : UART初始化函数
 * @param   : uart_id     - 串口ID
 * @param   : buad        - 波特率
 * @param   : prt_cf      - 串口接收回调函数
 * @return  : none
 */
void UARTx_Init(UART_IDX uart_id, uint32_t buad, Uart_prt prt_cf)
{
    switch (uart_id) {
    case UART_0:
        /*初始化 485使能引脚*/
        //GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeOut_PP_20mA);

        /* 配置串口1：先配置IO口模式，再配置串口 */
       // GPIOADigitalCfg(ENABLE,GPIO_Pin_0);
        R16_PIN_ALTERNATE &= ~(1<<14);      //启用PA0,PA1的UART功能

        GPIOA_SetBits(bTXD_2);
        GPIOA_ModeCfg(bRXD_2, GPIO_ModeIN_PU);      // RXD-配置上拉输入
        GPIOA_ModeCfg(bTXD_2, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出，注意先让IO口输出高电平
        UART_Remap(ENABLE, UART_TX_REMAP_PA1, UART_RX_REMAP_PA0);

//        GPIOA_SetBits(bTXD_0);
//        GPIOA_ModeCfg(bRXD_0, GPIO_ModeIN_PU);      // RXD-配置上拉输入
//        GPIOA_ModeCfg(bTXD_0, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出，注意先让IO口输出高电平
//        UART_Remap(ENABLE, UART_TX_REMAP_PA3, UART_RX_REMAP_PA2);

        //UART_DefInit();
        UART_BaudRateCfg(buad);
        R8_UART_FCR = RB_FCR_FIFO_EN;//(2 << 6) | RB_FCR_FIFO_EN; // FIFO打开，1 0     触发点4字节
        R8_UART_LCR = RB_LCR_WORD_SZ;
        R8_UART_IER = RB_IER_TXD_EN;
        R8_UART_DIV = 1;

        UART_ByteTrigCfg( UART_7BYTE_TRIG );
        UART_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT );
//        UART_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT| RB_IER_THR_EMPTY);
        PFIC_EnableIRQ(UART_IRQn);

        memset(&g_uart[UART_0],0,sizeof(UART_t));
        Set_Uart_recvTimeout(&g_uart[UART_0],buad);
        g_uart[UART_0].processing_cf = prt_cf;


        break;
    }

}


void Set_Uart_recvTimeout(UART_t *set_uart,uint32_t baud)
{
    if(baud == 115200)
    {
        set_uart->RecvTimeout = Recv_115200_TimeOut;
    }else if(baud == 9600)
    {
        set_uart->RecvTimeout = Recv_9600_TimeOut;
    }else if(baud == 2400)
    {
        set_uart->RecvTimeout = Recv_2400_TimeOut;
    }else
    {
        set_uart->RecvTimeout = 20;
    }
}

/*********************************************************************
 * @fn      UART0_IRQHandler
 *
 * @brief   UART0中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void UART_IRQHandler(void)
{
    volatile uint8_t i;

    switch(UART_GetITFlag())
    {
        case UART_II_LINE_STAT: // 线路状态错误
            i = UART_GetLinSTA();
            break;
        case UART_II_RECV_RDY: // 数据达到设置触发点
        case UART_II_RECV_TOUT: // 接收超时，暂时一帧数据接收完成
            i = R8_UART_RFC;
            if((g_uart[UART_0].RecvLen + i) >= USART_BUFFER_SIZE) g_uart[UART_0].RecvLen = 0;
            i = UART_RecvString(&g_uart[UART_0].RecvBuffer[g_uart[UART_0].RecvLen]);
            g_uart[UART_0].RecvLen += i;
            g_uart[UART_0].RecvIdleTiming = SysTick_1ms;

            g_uart[UART_0].Receiving = 0x01;
            break;
        case UART_II_THR_EMPTY: // 发送缓存区空，可继续发送
            break;

        default:
            break;
    }

}

/*********************************************************************
 * @fn      UART0_RECEIVE
 *
 * @brief   UART0
 *
 * @return  none
 */
void UART_RECEIVE(void)
{
    uint8_t rev = 0xFF;
    uint16_t i = 0;
    if(g_uart[UART_0].Receiving == 1)
    {
        if(SysTick_1ms - g_uart[UART_0].RecvIdleTiming > g_uart[UART_0].RecvTimeout)
        {
            g_uart[UART_0].RecvIdleTiming = SysTick_1ms;
            /*判断RX FIFO中是否还有没有数据*/
            if(UART_GetLinSTA() & 0x01)
            {
                i = R8_UART_RFC;
                if((g_uart[UART_0].RecvLen + i) >= USART_BUFFER_SIZE)   g_uart[UART_0].RecvLen = 0;
                i = UART_RecvString(&g_uart[UART_0].RecvBuffer[g_uart[UART_0].RecvLen]);
                g_uart[UART_0].RecvLen += i;
                return ;
            }
          // printf("UART0_RECEIVE len:%d %08x \r\n",g_uart[UART_0].RecvLen,UART0_RecvInPtr);
          // Dbg_Print_Buff(DBG_BIT_PC_COMM,"buff:",g_uart[UART_0].RecvBuffer,g_uart[UART_0].RecvLen);

            g_uart[UART_0].Receiving = 0;


            memcpy(g_Dealbuf,g_uart[UART_0].RecvBuffer,g_uart[UART_0].RecvLen);
            g_DealLen = g_uart[UART_0].RecvLen;


            if(g_uart[UART_0].processing_cf != NULL){
                rev = g_uart[UART_0].processing_cf(g_Dealbuf,g_DealLen);
            }

            g_uart[UART_0].RecvLen = 0;
            g_uart[UART_0].Receiving = 0;

            memset(g_Dealbuf,0x00,g_DealLen);
            g_DealLen = 0x00;

        }
    }
}

