#include <stdio.h>
#include "OB6627.h"
#include "uart.h"

volatile uint8_t  g_UartRxData[UART_RX_SIZE];
volatile uint32_t g_UartRxCounter = 0x00;
volatile uint32_t g_UartInterrupt = 0x00;
OB_UART_Type* g_uart_par;


void UART0_IRQHandler(void)
{
    if ((OB_UART0->ULSR & UART_INT_RBR) == UART_INT_RBR)
    {
        g_UartRxData[g_UartRxCounter] = OB_UART0->URBR;
        g_UartRxCounter++;
        g_UartInterrupt = 0x01;
    }
    else if ((OB_UART0->ULSR & UART_INT_TEMT) == UART_INT_TEMT)
    {
        UART_DisableInt(OB_UART0, UART_INT_THRE);
    }
}

void UART1_IRQHandler(void)
{
    if ((OB_UART1->ULSR & UART_INT_RBR) == UART_INT_RBR)
    {
        g_UartRxData[g_UartRxCounter] = OB_UART1->URBR;
        g_UartRxCounter++;
        g_UartInterrupt = 0x01;
    }
    else if ((OB_UART1->ULSR & UART_INT_TEMT) == UART_INT_TEMT)
    {
        UART_DisableInt(OB_UART1, UART_INT_THRE);
    }
}

void UART_DisableInt(OB_UART_Type* pUart, uint32_t nInterruptFlag )
{
    pUart->UIER &= ~nInterruptFlag;
}



void UART_EnableInt(OB_UART_Type* pUart, uint32_t nInterruptFlag )
{
    pUart->UIER = nInterruptFlag;
}


void UART_Open(OB_UART_Type* pUart, uint32_t nBaudRate)
{
    uint32_t nClock, nBuff;
    g_uart_par = pUart;
    if (pUart == OB_UART0)
        nClock = GetPeripheralClock(APB_UART0);
    else
        nClock = GetPeripheralClock(APB_UART1);

    nBuff = nClock / nBaudRate ;
    pUart->UDL = nBuff;
    pUart->ULCR = UART_WORD_LEN_8 | UART_STOP_BIT_1 | UART_PARITY_NONE;
}

uint32_t UART_Read(OB_UART_Type* pUart, uint8_t *pRxBuf, uint32_t nReadBytes)
{
    uint32_t nCount, nDelay;

    for (nCount = 0; nCount < nReadBytes; nCount++)
    {
        nDelay = 0x04000000;
        while(1)
        {
            if (nDelay == 0x00)
                return 0x00;

            if ((pUart->ULSR & UART_STATUS_RDR) == UART_STATUS_RDR)
            {
                pRxBuf[nCount] = pUart->URBR;
                break;
            }
            nDelay--;
        }
    }
    return nReadBytes;
}

uint32_t UART_Write(OB_UART_Type* pUart, uint8_t *pTxBuf, uint32_t nWriteBytes)
{
    uint32_t nCount, nDelay;

    for (nCount = 0; nCount < nWriteBytes; nCount++)
    {
        pUart->UTHR = pTxBuf[nCount];

        nDelay = 0x04000000;
        while(1)
        {
            if (nDelay == 0x00)
                return 0x00;

            if ((pUart->ULSR & UART_STATUS_TEMT) == UART_STATUS_TEMT)
                break;
            nDelay--;
        }
    }
    return nWriteBytes;
}


/*******************************************************************************
* Function Name  :  int fputc(int ch, FILE *f)
* Description    :
* Input          : int ch, FILE *f
* Output         :
* Return         : int ch
*******************************************************************************/
int fputc(int ch, FILE *f)
{
    uint8_t Buff;
    Buff = (uint8_t)ch;
    return UART_Write(g_uart_par, &Buff, 1);
}
/*******************************************************************************
   Function Name  : fputc
   Description        : redefine getc function,use scanf with uart input
   Input                  : FILE *f
   Output               :
* Return               : int ch
********************************************************************************/
int fgetc(FILE *f)
{
    uint8_t Buff;
    UART_Read(g_uart_par, &Buff, 1);
    return (int)Buff;
}
