#include "bsp_uart.h"

UART_StatusTypeDef UART_Transmit(UART_HandleTypeDef *huart, uint8_t *fu8_Data, uint32_t fu32_Size, uint32_t fu32_Timeout)
{
    uint32_t lu32_Timeout;
    
    assert_param(IS_UART_ALL_INSTANCE(huart->Instance));
    
    if(_IS_UART_HALFDUPLEX_MODE(huart->Instance))
    {
        _UART_RX_DISABLE(huart->Instance);
    }

    huart->TxCount = 0;
    
    while (fu32_Size--) 
    {
        huart->Instance->DR = *fu8_Data++;

        huart->TxCount++;
        
        /* have no timeout */
        if (fu32_Timeout == 0) 
        {
            while (huart->Instance->FR & UART_FR_TXFF);
        }
        else 
        {
            lu32_Timeout = fu32_Timeout *256;
            
            while (huart->Instance->FR & UART_FR_TXFF)
            {
                if (lu32_Timeout-- == 0) 
                {
                    return UART_TIMEOUT;
                }
            }
        }
    }
    
    UART_Wait_TX_Done(huart->Instance);
    
    if(_IS_UART_HALFDUPLEX_MODE(huart->Instance))
    {
        _UART_RX_ENABLE(huart->Instance);
    }
    
    return UART_OK;
}

UART_StatusTypeDef UART_Receive(UART_HandleTypeDef *huart, uint8_t *fu8_Data, uint32_t fu32_Size, uint32_t fu32_Timeout)
{
    uint32_t lu32_Timeout;
    
    assert_param(IS_UART_ALL_INSTANCE(huart->Instance));

    huart->RxCount = 0;

    while (fu32_Size--) 
    {
        if (fu32_Timeout == 0) 
        {
            while(huart->Instance->FR & UART_FR_RXFE);
            
            *fu8_Data++ = huart->Instance->DR;
            
            huart->RxCount++;
        }
        else 
        {
            lu32_Timeout = fu32_Timeout * 256;
            
            while(huart->Instance->FR & UART_FR_RXFE)
            {
                if (lu32_Timeout-- == 0) 
                {
                    return UART_TIMEOUT;
                }
            }

            *fu8_Data++ = huart->Instance->DR;

            huart->RxCount++;
        }
    }
    
    return UART_OK;
}

