/** ##########################################################################
**     Filename  : uart.c
**     Project   :
**     Module    :
**     Processor :
**     Version   : 1.0
**     Compiler  :
**     Date/Time :
**     Abstract  :
**     Contents  :
**     Note      :  uart底层
**
**     (c) Copyright dmdz Co.,Ltd
**  --------------------------------------------------------------------------
**               R E V I S I O N   H I S T O R Y
**  --------------------------------------------------------------------------
**  Date       Ver   Author             Description

**  -20230602-  --V1.0--  --mingyea---  --修改--

** #########################################################################*/

/*---------------------------------------------------------------------------
* I N C L U D E   F I L E S
----------------------------------------------------------------------------*/
#include "uart.h"
#include "nvic.h"

/*---------------------------------------------------------------------------
* D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
* T Y P E   D E F I N I T I O N S
----------------------------------------------------------------------------*/



/*---------------------------------------------------------------------------
* S T A T I C   V A R I A B L E S
----------------------------------------------------------------------------*/
static uart_s g_uart =
{
    0u
};
/*---------------------------------------------------------------------------
* G L O B A L   V A R I A B L E S
----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
* C O N S T A N T S
----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
* F U N C T I O N   P R O T O T Y P E
----------------------------------------------------------------------------*/




/*---------------------------------------------------------------------------
|Prototype          : uart_init
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 初始化
----------------------------------------------------------------------------*/
void uart_init(void)
{
    #ifdef USART_0_EN
    usart_0_gpio_init();
    FL_UART_Init(UART0, &g_UART0_InitStruct);
    /* NVIC中断配置 */
    NVIC_ClearPendingIRQ(UART0_IRQn);
    NVIC_DisableIRQ(UART0_IRQn);
    NVIC_SetPriority(UART0_IRQn, NVIC_PRIORITY_USART0); //中断优先级配置
    NVIC_EnableIRQ(UART0_IRQn);
    #endif

    #ifdef USART_1_EN
    usart_1_gpio_init();
    FL_UART_Init(UART1, &g_UART1_InitStruct);
    /* NVIC中断配置 */
    NVIC_ClearPendingIRQ(UART1_IRQn);
    NVIC_DisableIRQ(UART1_IRQn);
    NVIC_SetPriority(UART1_IRQn, NVIC_PRIORITY_USART1); //中断优先级配置
    NVIC_EnableIRQ(UART1_IRQn);
    #endif

    #ifdef USART_3_EN
    usart_3_gpio_init();
    FL_UART_Init(UART3, &g_UART3_InitStruct);
    /* NVIC中断配置 */
    NVIC_ClearPendingIRQ(UART3_IRQn);
    NVIC_DisableIRQ(UART3_IRQn);
    NVIC_SetPriority(UART3_IRQn, NVIC_PRIORITY_USART3); //中断优先级配置
    NVIC_EnableIRQ(UART3_IRQn);
    #endif

    #ifdef USART_4_EN
    usart_4_gpio_init();
    FL_UART_Init(UART4, &g_UART4_InitStruct);
    /* NVIC中断配置 */
    NVIC_ClearPendingIRQ(UART4_IRQn);
    NVIC_DisableIRQ(UART4_IRQn);
    NVIC_SetPriority(UART4_IRQn, NVIC_PRIORITY_USART4); //中断优先级配置
    NVIC_EnableIRQ(UART4_IRQn);
    #endif

    #ifdef USART_5_EN
    usart_5_gpio_init();
    FL_UART_Init(UART5, &g_UART5_InitStruct);
    /* NVIC中断配置 */
    NVIC_ClearPendingIRQ(UART5_IRQn);
    NVIC_DisableIRQ(UART5_IRQn);
    NVIC_SetPriority(UART5_IRQn, NVIC_PRIORITY_USART5); //中断优先级配置
    NVIC_EnableIRQ(UART5_IRQn);
    #endif

}


/*---------------------------------------------------------------------------
|Prototype          : uart_tx_start
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 初始化
----------------------------------------------------------------------------*/
u8 uart_tx_start(UART_Type *device, u8 *pdata, u8 length)
{
    u8 l_result = UART_OP_RESULT_OK;
    u8 i ;
    UART_Type *l_usart_dev = (UART_Type *)device;
    //做了长度的判断
    if( (length == 0u) || (length>UART_TX_BUFF_LENGTH) )
    {
        l_result = UART_OP_RESULT_FAILED;
    }
    else
    {
        if(g_uart.state == UART_STATE_IDLE)
        {
            for(i = 0; i < length; i++)
            {
                g_uart.tx_data[i] = pdata[i] ;
            }
            #ifdef UART_INSERT_PROTOCAL
            g_uart.cmd = g_uart.tx_data[3];
            #endif
            g_uart.timecount=0u;
            g_uart.byte_count=0u;
            g_uart.tx_byte_total=length;
            g_uart.result=UART_RESULT_INIT;
            g_uart.state=UART_STATE_TX;
            #if 0
            l_usart_dev->RBR = g_uart.tx_data[g_uart.byte_count];
            UART_SetTXEInterrupt(l_usart_dev, ENABLE);
            #else
            FL_UART_ClearFlag_TXShiftBuffEmpty(device);
            FL_UART_EnableIT_TXShiftBuffEmpty(device);
            FL_UART_WriteTXBuff(device,g_uart.tx_data[g_uart.byte_count]);
            #endif
        }
        else
        {
            l_result = UART_OP_RESULT_BUSY;
        }
    }
    return l_result;
}

/*---------------------------------------------------------------------------
|Prototype          : uart_tx_isr_task
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 初始化
----------------------------------------------------------------------------*/
void uart_tx_isr_task(UART_Type *device)
{
    UART_Type *l_usart_dev = (UART_Type *)device;
    u8 l_result = UART_OP_RESULT_OK;
    g_uart.timecount=0u;
    g_uart.byte_count++;
    if(g_uart.byte_count>=g_uart.tx_byte_total)
    {
        g_uart.byte_count=0u;
        g_uart.result=UART_RESULT_TX_OK;
        #ifdef UART_INSERT_PROTOCAL
        if( (g_uart.cmd & 0x20) || (g_uart.cmd==USART_CMD_READ_VERSION) )
        {
            #ifdef UART_INSERT_PROTOCAL
            if( (g_uart.cmd & 0x20) )
            {
                g_uart.rx_byte_total=(g_uart.cmd &0x1fu)  + 4u;;
            }
            else
            {
                g_uart.rx_byte_total= USART_LEN_READ_VERSION  + 1u;
            }
            #else
            //
            #endif
            g_uart.state=UART_STATE_RX;
        }
        else
        {
            g_uart.state=UART_STATE_IDLE;
        }
        #else
        g_uart.rx_byte_total=0u;
        g_uart.state=UART_STATE_IDLE;
        #endif
        #if 0
        UART_SetTXEInterrupt(l_usart_dev, DISABLE);
        #else
        FL_UART_DisableIT_TXShiftBuffEmpty(device);
        FL_UART_EnableIT_RXBuffFull(device);
        #endif
        #ifdef UART_DEBUG_EN
        g_uart.tx_count++;
        #endif
    }
    else
    {
        #if 0
        l_usart_dev->RBR = g_uart.tx_data[g_uart.byte_count];
        #else
        //FL_UART_ClearFlag_TXShiftBuffEmpty(device);
        //FL_UART_EnableIT_TXShiftBuffEmpty(device);
        FL_UART_WriteTXBuff(device,g_uart.tx_data[g_uart.byte_count]);
        #endif
    }
}


/*---------------------------------------------------------------------------
|Prototype          : uart_rx_isr_task
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 初始化
----------------------------------------------------------------------------*/
void uart_rx_isr_task(UART_Type *device,u8 data)
{
    UART_Type *l_usart_dev = (UART_Type *)device;
    u8 l_len = UART_RX_BUFF_LENGTH;
    g_uart.timecount=0u;
    if(g_uart.state == UART_STATE_IDLE)
    {
        g_uart.byte_count=0u;
        g_uart.rx_data[g_uart.byte_count] = data;
        #ifdef UART_INSERT_PROTOCAL
        if( (g_uart.cmd & 0x20) )
        {
            g_uart.rx_byte_total=(g_uart.cmd &0x1fu)  + 4u;;
        }
        else
        {
            g_uart.rx_byte_total= USART_LEN_READ_VERSION  + 1u;
        }
        #else
        //
        #endif
        g_uart.byte_count++;
        g_uart.state = UART_STATE_RX;
    }
    else if(g_uart.state == UART_STATE_RX)
    {
        g_uart.rx_data[g_uart.byte_count] = data;
        g_uart.byte_count++;
        #ifdef UART_INSERT_PROTOCAL
        if(g_uart.byte_count>=g_uart.rx_byte_total)
        {
            //g_uart.byte_total=g_uart.byte_count;
            g_uart.byte_count=0u;
            g_uart.result=UART_RESULT_RX_OK;
            g_uart.state=UART_STATE_IDLE;
            #ifdef UART_DEBUG_EN
            g_uart.rx_count++;
            #endif
        }
        #endif
        if(g_uart.byte_count>=UART_RX_BUFF_LENGTH)
        {
            //g_uart.byte_total=g_uart.byte_count;
            g_uart.byte_count=0u;
            FL_UART_DisableIT_TXShiftBuffEmpty(device);
            FL_UART_DisableIT_RXBuffFull(device);
            g_uart.result=UART_RESULT_OVER_LEN;
            g_uart.state=UART_STATE_IDLE;
        }
    }
    else
    {
        //
    }
}


/*---------------------------------------------------------------------------
|Prototype          : uart_timeout_task
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 初始化
----------------------------------------------------------------------------*/
void uart_timeout_task(UART_Type *device)
{
    UART_Type *l_usart_dev = (UART_Type *)device;
    u8 l_state;
    UART_SR_ALLOC();
    UART_CRITICAL_ENTER();
    l_state = g_uart.state;
    UART_CRITICAL_EXIT();
    if(l_state != UART_STATE_IDLE)
    {
        UART_CRITICAL_ENTER();
        g_uart.timecount++;
        if(g_uart.timecount>=UART_RECOVERY_TIMEOUT)
        {
            g_uart.timecount =0u;
            if(g_uart.state == UART_STATE_TX)
            {
                g_uart.result=UART_RESULT_TIMEOUT;
                #ifdef UART_DEBUG_EN
                g_uart.tx_count_timeout++;
                #endif
            }
            else
            {
                g_uart.rx_byte_total = g_uart.byte_count;  //收完后的把总字长，保存
                #ifdef UART_INSERT_PROTOCAL
                g_uart.result=UART_RESULT_TIMEOUT;
                #else
                g_uart.result=UART_RESULT_RX_OK;
                #endif
                #ifdef UART_DEBUG_EN
                g_uart.rx_count_timeout++;
                #endif
            }
            g_uart.byte_count=0u;
            FL_UART_DisableIT_RXBuffFull(device);
            g_uart.state=UART_STATE_IDLE;
        }
        UART_CRITICAL_EXIT();
    }
}


/*---------------------------------------------------------------------------
|Prototype          : uart_task
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        :
----------------------------------------------------------------------------*/
void uart_task(void)
{
    uart_timeout_task(UART5);
}


/*---------------------------------------------------------------------------
|Prototype          : uart_get_result
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        : 
----------------------------------------------------------------------------*/
u8 uart_get_result(void)
{
    return g_uart.result;
}


/*---------------------------------------------------------------------------
|Prototype          : uart_get_rx_data
|Called by          :
|Preconditions      :
|Input parameters   :
|Output parameters  :
|Return value       :
|Description        :
----------------------------------------------------------------------------*/
u8 uart_get_rx_data(u8 *pdata,u8 len)
{
    u8 i;
    u8 l_result=0u;
    u8 l_len = len;
    if(l_len > UART_RX_BUFF_LENGTH)    //
    {
        l_len = UART_RX_BUFF_LENGTH;
    }
    for(i = 0; i < l_len; i++)
    {
        pdata[i] = g_uart.rx_data[i];
    }
    return l_result;
}


/**
  * @brief  UART初始化
  * @param  UARTx: 串口号
  *         rate:  波特率
  * @retval void
  */
void Uartx_Init(UART_Type *device, uint32_t baud_rate)
{
    //FL_UART_InitTypeDef UART_InitStruct = {0};

    switch ((uint32_t)device)
    {
        case UART0_BASE:

            #ifdef USART_0_EN
            //usart_0_gpio_init();  //在GPIO表格中配置
            FL_UART_Init(UART0, &g_UART0_InitStruct);
            /* NVIC中断配置 */
            NVIC_ClearPendingIRQ(UART0_IRQn);
            NVIC_DisableIRQ(UART0_IRQn);
            NVIC_SetPriority(UART0_IRQn, NVIC_PRIORITY_USART0); //中断优先级配置
            NVIC_EnableIRQ(UART0_IRQn);
            #endif

            break;

        case UART1_BASE:

            #ifdef USART_1_EN
            //usart_1_gpio_init(); //在GPIO表格中配置
            FL_UART_Init(UART1, &g_UART1_InitStruct);
            /* NVIC中断配置 */
            NVIC_ClearPendingIRQ(UART1_IRQn);
            NVIC_DisableIRQ(UART1_IRQn);
            NVIC_SetPriority(UART1_IRQn, NVIC_PRIORITY_USART1); //中断优先级配置
            NVIC_EnableIRQ(UART1_IRQn);
            #endif

            break;

        case UART3_BASE:

            #ifdef USART_3_EN
            //usart_3_gpio_init();  //在GPIO表格中配置
            FL_UART_Init(UART3, &g_UART3_InitStruct);
            /* NVIC中断配置 */
            NVIC_ClearPendingIRQ(UART3_IRQn);
            NVIC_DisableIRQ(UART3_IRQn);
            NVIC_SetPriority(UART3_IRQn, NVIC_PRIORITY_USART3); //中断优先级配置
            NVIC_EnableIRQ(UART3_IRQn);
            #endif

            break;


        case UART4_BASE:

            #ifdef USART_4_EN
            //usart_4_gpio_init();  //在GPIO表格中配置
            FL_UART_Init(UART4, &g_UART4_InitStruct);
            /* NVIC中断配置 */
            NVIC_ClearPendingIRQ(UART4_IRQn);
            NVIC_DisableIRQ(UART4_IRQn);
            NVIC_SetPriority(UART4_IRQn, NVIC_PRIORITY_USART4); //中断优先级配置
            NVIC_EnableIRQ(UART4_IRQn);
            #endif

            break;

        case UART5_BASE:

            #ifdef USART_5_EN
            //usart_5_gpio_init();  //在GPIO表格中配置
            FL_UART_Init(UART5, &g_UART5_InitStruct);
            /* NVIC中断配置 */
            NVIC_ClearPendingIRQ(UART5_IRQn);
            NVIC_DisableIRQ(UART5_IRQn);
            NVIC_SetPriority(UART5_IRQn, NVIC_PRIORITY_USART5); //中断优先级配置
            NVIC_EnableIRQ(UART5_IRQn);
            #endif

            break;

        default:
            break;
    }

}










