/*
  ******************************************************************************
  * @file    fxx_it.c
  * @brief   fxx_it source File.
  ******************************************************************************
*/

#include "fxx_it.h"
#include "app.h"


extern volatile uint32_t gu32_SystemCount; 

/*********************************************************************************
* Function    : HardFault_Handler
* Description : Hard Fault handle, while(1) loop, wait for debug 
* Input       : none 
* Output      : none   
* Author      : xwl                           
**********************************************************************************/  
void HardFault_Handler(void)
{
    while(1);   
} 


/*********************************************************************************
* Function    : SysTick_Handler
* Description : System tick handler
* Input       : none 
* Output      : none 
* Author      : xwl                         
**********************************************************************************/
void SysTick_Handler(void)
{
    gu32_SystemCount++;  
}

void UART_IRQHandler(UART_HandleTypeDef *huart)
{
    uint32_t read_bytes_number;
    uint32_t isrflags;
    uint32_t errorflags;
    UART_TypeDef* UARTx;
    
    UARTx = huart->Instance;
    
    assert_param (IS_UART_ALL_INSTANCE(UARTx));    

    isrflags = READ_REG(UARTx->MIS);

    errorflags = (READ_REG(UARTx->RIS) & (UART_RIS_ERROR_BITS));  

    if (isrflags & UART_MIS_TXI) 
    {
        /* Clear TXI Status */
        UART_ClearITPendingBit(UARTx, UART_IT_TXI);

        for(;;)
        {
            if(huart->TxCount >= huart->TxSize) 
            {                             
                huart->TxBusy = false;
         
                /* Disable TX interrupt */
                UART_ITConfig(UARTx, UART_IT_TXI, DISABLE);
         
                if(huart->TxCpltCallback)
                    huart->TxCpltCallback(huart);

                return;
            }

            if (READ_BIT(UARTx->FR, UART_FR_TXFF))
            {
                break;
            }
            
            UARTx->DR = huart->TxData[huart->TxCount++];
        }
    }


    /* RXI */ 
    if (isrflags & UART_MIS_RXI) 
    {
        read_bytes_number = 0;   
        /* Clear RXI Status */
        UART_ClearITPendingBit(UARTx, UART_IT_RXI);
                                
        /* read data out untill RXFIFO empty */
        while(!READ_BIT(UARTx->FR, UART_FR_RXFE))
        {
            /* Store Data in buffer */
            huart->RxData[huart->RxCount++] = UARTx->DR;
            if(huart->RxCount >= BUF_SIZE)
                huart->RxCount = 0;

            read_bytes_number++;  
            
            if (read_bytes_number == fifo_level_minus1)   
            {
                break;   
            }
        }
    }
    else if(isrflags & UART_MIS_RTI)
    {
        /*clear RTI Status */
        UART_ClearITPendingBit(UARTx, UART_IT_RTI);

        while(!READ_BIT(UARTx->FR, UART_FR_RXFE))
        {
            huart->RxData[huart->RxCount++] = UARTx->DR;
            if(huart->RxCount >= BUF_SIZE)
                huart->RxCount = 0;
        }

        huart->RxBusy = false;
        
        if(huart->RxCpltCallback)
            huart->RxCpltCallback(huart);
    }	
	
	/* if some errors occurred */
    if(errorflags != 0)
    {
		/* UART parity error interrupt occurred */
        if ( (errorflags & UART_RIS_PEI) != 0)
        {
	    	/* Clear parity error status */
            UART_ClearITPendingBit(UARTx, UART_IT_PEI);
	      	huart->ErrorCode |= UART_ERROR_PE; 
	    }

	    /* UART break error interrupt occurred */
        if ( (errorflags & UART_RIS_BEI) != 0) 
	    {
	    	UART_ClearITPendingBit(UARTx, UART_IT_BEI);
	      	huart->ErrorCode |= UART_ERROR_NE;
	    }

	    /* UART frame error interrupt occurred */
	    if ( (errorflags & UART_RIS_FEI) != 0) 
	    {
	    	UART_ClearITPendingBit(UARTx, UART_IT_FEI);
	      	huart->ErrorCode |= UART_ERROR_FE;
	    }

	    /* UART Over-Run interrupt occurred */
	    if ( (errorflags & UART_RIS_OEI) != 0) 
	    {
	    	UART_ClearITPendingBit(UARTx, UART_IT_OEI);
	      	huart->ErrorCode |= UART_ERROR_ORE;
	    }
        if(huart->ErrorCallback)
            huart->ErrorCallback(huart); 
	}
}


void UART2_IRQHandler(void)
{
    UART_IRQHandler(&UartHandle);
}




