#include "RTE_UART.h"
#include "uart.h"
#include "cgc.h"
#include "gpio.h"
#include "isr.h"


uint32_t RTE_UART_Init(UART_Channel_en_t enUARTCh, UART_Channel_Config_st_t *penUARTCfg);
void     RTE_UART_Sleep_Init(UART_Channel_en_t enUARTCh);
/*******************************************************************/

/*******************************************************/
typedef struct
{
    uint8_t  u8UARTCount;      /*发送计数*/
    uint8_t  u8UARTLEN;        /*发送数据总长*/
    uint8_t  u8UARTTXBusyFlag; /*发送是否忙标志  0:idle  1:busy */
    uint8_t *pu8UARTDataBuf;   /*要发送数据的指针*/
} UART_Ctr_st_t;
/*******************************************************/

static UART_Ctr_st_t stUARTCtr0;
static UART_Ctr_st_t stUARTCtr1;
static UART_Ctr_st_t stUARTCtr2;


static UART_Channel_Config_st_t stUARTCh0Cfg;
static UART_Channel_Config_st_t stUARTCh1Cfg;
static UART_Channel_Config_st_t stUARTCh2Cfg;


/*******************************************************/
static void RTE_UART_Variate_Init(void);
static void RTE_UART_Variate_Init(void)
{
    stUARTCtr0.u8UARTCount      = 0U;
    stUARTCtr0.u8UARTLEN        = 0U;
    stUARTCtr0.u8UARTTXBusyFlag = 0U;
    stUARTCtr0.pu8UARTDataBuf   = 0U;

    stUARTCh0Cfg.u32UARTChEn            = 0U;
    stUARTCh0Cfg.u32UARTbps             = 0U;
    stUARTCh0Cfg.pfnUARTConfirmCallBack = 0U;
    stUARTCh0Cfg.pfnUARTReadMsgCallBack = 0U;

    stUARTCtr1.u8UARTCount      = 0U;
    stUARTCtr1.u8UARTLEN        = 0U;
    stUARTCtr1.u8UARTTXBusyFlag = 0U;
    stUARTCtr1.pu8UARTDataBuf   = 0U;

    stUARTCh1Cfg.u32UARTChEn            = 0U;
    stUARTCh1Cfg.u32UARTbps             = 0U;
    stUARTCh1Cfg.pfnUARTConfirmCallBack = 0U;
    stUARTCh1Cfg.pfnUARTReadMsgCallBack = 0U;

    stUARTCtr2.u8UARTCount      = 0U;
    stUARTCtr2.u8UARTLEN        = 0U;
    stUARTCtr2.u8UARTTXBusyFlag = 0U;
    stUARTCtr2.pu8UARTDataBuf   = 0U;

    stUARTCh2Cfg.u32UARTChEn            = 0U;
    stUARTCh2Cfg.u32UARTbps             = 0U;
    stUARTCh2Cfg.pfnUARTConfirmCallBack = 0U;
    stUARTCh2Cfg.pfnUARTReadMsgCallBack = 0U;
}
/*****************************************************************************
* Function Name: uart_callback_error
* @brief
* @param  None
* @return None
******************************************************************************/
void uart_callback_error(uint8_t err_type);
void uart_callback_error(uint8_t err_type)
{
    //user edit here when appear error
}

/*
返回设置成功的波特率，返回0xFFFFFFFF表示设置失败。
*/
uint32_t RTE_UART_Init(UART_Channel_en_t enUARTCh, UART_Channel_Config_st_t *penUARTCfg)
{   
    int8_t ret = SCI_SUCCESS; 
    UART_InitTypeDef  stUART_InitStruct;
    GPIO_InitTypeDef GPIO_InitStruct;
    SCIAFSelect_TypeDef enUartChanell;


    stUART_InitStruct.UART_Mode = 0;
    stUART_InitStruct.UART_BaudRate = 0;
    stUART_InitStruct.UART_Parity = 0;
    stUART_InitStruct.UART_StopBits = 0;
    stUART_InitStruct.UART_WordLength = 0;
    stUART_InitStruct.phase = 0;
    stUART_InitStruct.bitorder = 0;

    RTE_UART_Variate_Init( );

    if ( (enUARTCh < UART_CH_MAX) && (penUARTCfg->u32UARTChEn) && (penUARTCfg->u32UARTbps) )
    {
        switch (enUARTCh)
        {
            case UART_CH0:
                enUartChanell = UART0;    

                GPIO_PinAFConfig(GPIO_PORT5, GPIO_Pin_1, GPIO_P51, GROUP_AF_ODEFAULT);
                GPIO_PinAFConfig(GPIO_PORT5, GPIO_Pin_0, GPIO_P50, GROUP_AF_ODEFAULT);

                /*TX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_1;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;
                GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;
                GPIO_InitStruct.GPIO_Level   = GPIO_Level_HIGH;	
                GPIO_InitStruct.GPIO_Ctrl  = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT5, &GPIO_InitStruct);

                /*RX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_0 ;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;
                GPIO_InitStruct.GPIO_Ctrl   = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT5, &GPIO_InitStruct);

                /*USART CONFIG*/
                stUART_InitStruct.UART_BaudRate = penUARTCfg->u32UARTbps;
                stUART_InitStruct.UART_WordLength = UART_WordLength_8b;
                stUART_InitStruct.UART_StopBits = UART_StopBits_1;//一个停止位
                stUART_InitStruct.UART_Parity = UART_Parity_No;//无奇偶校验位
                stUART_InitStruct.phase = UART_Phase_Normal;
                stUART_InitStruct.bitorder = UART_Bit_LSB;
                stUART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 

                ISR_Register(ST0_IRQn, UART_CH0_TX_ISR);     //串口0发送中断服务路径注册
                ISR_Register(SR0_IRQn, UART_CH0_RX_ISR);  //串口0接收中断服务路径注册     

                break;
            case UART_CH1:
                enUartChanell = UART1;       

                GPIO_PinAFConfig(GPIO_PORT0, GPIO_Pin_2, GPIO_P02, GROUP_AF_ODEFAULT);
                GPIO_PinAFConfig(GPIO_PORT0, GPIO_Pin_3, GPIO_P03, GROUP_AF_ODEFAULT);

                /*TX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_2;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;
                GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;
                GPIO_InitStruct.GPIO_Level   = GPIO_Level_HIGH;	
                GPIO_InitStruct.GPIO_Ctrl   = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT0, &GPIO_InitStruct);

                /*RX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_3;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;
                GPIO_InitStruct.GPIO_Ctrl   = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT0, &GPIO_InitStruct);

                /*USART CONFIG*/
                stUART_InitStruct.UART_BaudRate = penUARTCfg->u32UARTbps;
                stUART_InitStruct.UART_WordLength = UART_WordLength_8b;
                stUART_InitStruct.UART_StopBits = UART_StopBits_1;//一个停止位
                stUART_InitStruct.UART_Parity = UART_Parity_No;//无奇偶校验位
                stUART_InitStruct.phase = UART_Phase_Normal;
                stUART_InitStruct.bitorder = UART_Bit_LSB;
                stUART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 

                ISR_Register(ST1_IRQn, UART_CH1_TX_ISR);     //串口1发送中断服务路径注册
                ISR_Register(SR1_IRQn, UART_CH1_RX_ISR);  //串口1接收中断服务路径注册        
                break;
            case UART_CH2:
                enUartChanell = UART2; 
                GPIO_PinAFConfig(GPIO_PORT7, GPIO_Pin_6, GPIO_P76, GROUP_AF_RXD2);
                GPIO_PinAFConfig(GPIO_PORT7, GPIO_Pin_7, GPIO_P77, GROUP_AF_TXD2);

                /*TX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_7;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;
                GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;
                GPIO_InitStruct.GPIO_Level   = GPIO_Level_HIGH;		
                GPIO_InitStruct.GPIO_Ctrl   = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT7, &GPIO_InitStruct);

                /*RX GPIO CONFIG*/
                GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_6;
                GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;
                GPIO_InitStruct.GPIO_Ctrl   = GPIO_Control_DIG;
                GPIO_Init(GPIO_PORT7, &GPIO_InitStruct);

                /*USART CONFIG*/
                stUART_InitStruct.UART_BaudRate = penUARTCfg->u32UARTbps;
                stUART_InitStruct.UART_WordLength = UART_WordLength_8b;
                stUART_InitStruct.UART_StopBits = UART_StopBits_1;//一个停止位
                stUART_InitStruct.UART_Parity = UART_Parity_No;//无奇偶校验位
                stUART_InitStruct.phase = UART_Phase_Normal;
                stUART_InitStruct.bitorder = UART_Bit_LSB;
                stUART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 


                stUARTCh2Cfg.pfnUARTReadMsgCallBack  = penUARTCfg->pfnUARTReadMsgCallBack;

                ISR_Register(ST2_IRQn, UART_CH2_TX_ISR);     //串口2发送中断服务路径注册
                ISR_Register(SR2_IRQn, UART_CH2_RX_ISR);  //串口2接收中断服务路径注册                
                break;    
            default:
                break;
        }
        ret = UART_Init(enUartChanell, &stUART_InitStruct); 
        if (ret)
        {
            SCI_ERROR_LOG(ret);        
        } 
    }
    return penUARTCfg->u32UARTbps;
}

void RTE_UART_Sleep_Init(UART_Channel_en_t enUARTCh)
{
   
    SCIAFSelect_TypeDef enUartChanell;

    if ( (enUARTCh < UART_CH_MAX) )
    {
        switch (enUARTCh)
        {
            case UART_CH0:
                enUartChanell = UART0;
                break;

            case UART_CH1:
                enUartChanell = UART1;
                break;

            case UART_CH2:
                enUartChanell = UART2;
                break;

            default:
                enUartChanell = UART0;
                break;    
        }
        UART_DeInit(enUartChanell);
    }
    RTE_UART_Variate_Init( );
}
/*
0：idle
1：busy
*/
uint8_t UART_Ch0_Get_TX_Busy_Flag(void)
{
    uint8_t u8Status = 0U;
    if ((SCI0->UART0.TSSR & 0x0060) || (stUARTCtr0.u8UARTTXBusyFlag) )
    {
        u8Status = 1U;
    }
    return u8Status;
}
uint8_t UART_Ch1_Get_TX_Busy_Flag(void)
{
    uint8_t u8Status = 0U;
    if ((SCI0->UART1.TSSR & 0x0060) || (stUARTCtr1.u8UARTTXBusyFlag) )
    {
        u8Status = 1U;
    }
    return u8Status;
}
uint8_t UART_Ch2_Get_TX_Busy_Flag(void)
{
    uint8_t u8Status = 0U;
    if ((SCI1->UART2.TSSR & 0x0060) || (stUARTCtr2.u8UARTTXBusyFlag) )
    {
        u8Status = 1U;
    }
    return u8Status;
}
uint8_t UART_Ch3_Get_TX_Busy_Flag(void)
{
    uint8_t u8Status = 0U;
    // if ((SCI0->UART3.TSSR & 0x0060) || (stUARTCtr3.u8UARTTXBusyFlag) )
    // {
    //     u8Status = 1U;
    // }
    return u8Status;
}
/*
Data：要发送数据的指针，
请确认是全局变量的指针，且指向的数据在发送完成之前不会被改变。
*/
void UART_Ch0_Send_Multiple_Byte(uint8_t *Data, uint8_t Len)
{
    if ( UART_Ch0_Get_TX_Busy_Flag( ) == 0U )
    {
        stUARTCtr0.u8UARTCount      = 1U;
        stUARTCtr0.u8UARTLEN        = Len;
        stUARTCtr0.u8UARTTXBusyFlag = 1U;
        stUARTCtr0.pu8UARTDataBuf   = Data;
        UART0_TX                  = stUARTCtr0.pu8UARTDataBuf [ 0U ];
    }
}
void UART_Ch1_Send_Multiple_Byte(uint8_t *Data, uint8_t Len)
{
    if ( UART_Ch1_Get_TX_Busy_Flag( ) == 0U )
    {
        stUARTCtr1.u8UARTCount      = 1U;
        stUARTCtr1.u8UARTLEN        = Len;
        stUARTCtr1.u8UARTTXBusyFlag = 1U;
        stUARTCtr1.pu8UARTDataBuf   = Data;
        UART1_TX                  = stUARTCtr1.pu8UARTDataBuf [ 0U ];
    }
}
void UART_Ch2_Send_Multiple_Byte(uint8_t *Data, uint8_t Len)
{
    if ( UART_Ch2_Get_TX_Busy_Flag( ) == 0U )
    {
        stUARTCtr2.u8UARTCount      = 1U;
        stUARTCtr2.u8UARTLEN        = Len;
        stUARTCtr2.u8UARTTXBusyFlag = 1U;
        stUARTCtr2.pu8UARTDataBuf   = Data;
        UART2_TX                  = stUARTCtr2.pu8UARTDataBuf [ 0U ];
    }
}
void UART_Ch3_Send_Multiple_Byte(uint8_t *Data, uint8_t Len)
{
    if ( UART_Ch3_Get_TX_Busy_Flag( ) == 0U )
    {
//        stUARTCtr3.u8UARTCount      = 1U;
//        stUARTCtr3.u8UARTLEN        = Len;
//        stUARTCtr3.u8UARTTXBusyFlag = 1U;
//        stUARTCtr3.pu8UARTDataBuf   = Data;
        ////UART3_TX                  = stUARTCtr3.pu8UARTDataBuf [ 0U ];
    }
}

void UART_CH0_RX_ISR(void)
{
    volatile uint8_t rx_data;
    volatile uint8_t err_type;

    INTC_ClearPendingIRQ(SR0_IRQn);
    err_type = UART_GetErrStaus(UART0, UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);

    if (err_type)
    {
		UART_ClearFlag(UART0,UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);
        uart_callback_error(err_type);
    }

    rx_data = UART0_RX;
    /*If no error is detected*/
    if ( stUARTCh0Cfg.pfnUARTReadMsgCallBack )
    {
        stUARTCh0Cfg.pfnUARTReadMsgCallBack(rx_data);
    }
}
void UART_CH1_RX_ISR(void)
{
    volatile uint8_t rx_data;
    volatile uint8_t err_type;

    INTC_ClearPendingIRQ(SR1_IRQn);
    err_type = UART_GetErrStaus(UART1, UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);

    if (err_type)
    {
		UART_ClearFlag(UART1,UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);
        uart_callback_error(err_type);
    }

    rx_data = UART1_RX;
    /*If no error is detected*/
    if ( stUARTCh1Cfg.pfnUARTReadMsgCallBack )
    {
        stUARTCh1Cfg.pfnUARTReadMsgCallBack(rx_data);
    }
}
void UART_CH2_RX_ISR(void)
{
    volatile uint8_t rx_data;
    volatile uint8_t err_type;


    INTC_ClearPendingIRQ(SR2_IRQn);
    err_type = UART_GetErrStaus(UART2, UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);

    if (err_type)
    {
        uart_callback_error(err_type);
		UART_ClearFlag(UART2,UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);
    }

    rx_data = UART2_RX;
    /*If no error is detected*/
    if ( stUARTCh2Cfg.pfnUARTReadMsgCallBack )
    {
        stUARTCh2Cfg.pfnUARTReadMsgCallBack(rx_data);
    }
}
void UART_CH3_RX_ISR(void)
{
    // volatile uint8_t rx_data;
    // volatile uint8_t err_type;


    // INTC_ClearPendingIRQ(SR3_IRQn);
    // err_type = UART_GetErrStaus(UART3, UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);

    // if (err_type)
    // {
    //     uart_callback_error(err_type);
	// 	UART_ClearFlag(UART3,UART_FLAG_FEF | UART_FLAG_PEF | UART_FLAG_OVF);
    // }

    // rx_data = UART3_RX;
    /*If no error is detected*/
    // if ( stUARTCh3Cfg.pfnUARTReadMsgCallBack )
    // {
    //     stUARTCh3Cfg.pfnUARTReadMsgCallBack(RLN33LURDR);
    // }
}

void UART_CH0_TX_ISR(void)
{
    INTC_ClearPendingIRQ(ST0_IRQn);
    if ( stUARTCtr0.u8UARTCount < stUARTCtr0.u8UARTLEN )
    {
        UART0_TX = stUARTCtr0.pu8UARTDataBuf [ stUARTCtr0.u8UARTCount++ ];
    }
    else
    {
        stUARTCtr0.u8UARTTXBusyFlag = 0U;
        if ( stUARTCh0Cfg.pfnUARTConfirmCallBack )
        {
            stUARTCh0Cfg.pfnUARTConfirmCallBack( );
        }
    }
}
void UART_CH1_TX_ISR(void)
{
    INTC_ClearPendingIRQ(ST1_IRQn);
    if ( stUARTCtr1.u8UARTCount < stUARTCtr1.u8UARTLEN )
    {
        UART1_TX = stUARTCtr1.pu8UARTDataBuf [ stUARTCtr1.u8UARTCount++ ];
    }
    else
    {
        stUARTCtr1.u8UARTTXBusyFlag = 0U;
        if ( stUARTCh1Cfg.pfnUARTConfirmCallBack )
        {
            stUARTCh1Cfg.pfnUARTConfirmCallBack( );
        }
    }
}
void UART_CH2_TX_ISR(void)
{
    INTC_ClearPendingIRQ(ST2_IRQn);
    if ( stUARTCtr2.u8UARTCount < stUARTCtr2.u8UARTLEN )
    {
        UART2_TX = stUARTCtr2.pu8UARTDataBuf [ stUARTCtr2.u8UARTCount++ ];
    }
    else
    {
        stUARTCtr2.u8UARTTXBusyFlag = 0U;
        if ( stUARTCh2Cfg.pfnUARTConfirmCallBack )
        {
            stUARTCh2Cfg.pfnUARTConfirmCallBack( );
        }
    }
}
void UART_CH3_TX_ISR(void)
{
    //INTC_ClearPendingIRQ(ST3_IRQn);
 
    // if ( stUARTCtr3.u8UARTCount < stUARTCtr3.u8UARTLEN )
    // {
    //     UART3_TX = stUARTCtr3.pu8UARTDataBuf [ stUARTCtr3.u8UARTCount++ ];
    // }
    // else
    // {
    //     stUARTCtr3.u8UARTTXBusyFlag = 0U;
    //     if ( stUARTCh3Cfg.pfnUARTConfirmCallBack )
    //     {
    //         stUARTCh3Cfg.pfnUARTConfirmCallBack( );
    //     }
    // }
}


