#include "bsp_serial.h"


#ifdef BSP_USING_UART1
Serial serial1;
void USART1_IRQHandler( void )
{
    _uartIsr( &serial1 );
}
#endif
#ifdef BSP_USING_UART2
Serial serial2;
//void USART2_IRQHandler(void)
//{
//  _uartIsr(&serial2);
// }

#endif
#ifdef BSP_USING_UART3
Serial serial3;
void USART3_IRQHandler( void )
{
    _uartIsr( &serial3 );
}

#endif
#ifdef BSP_USING_UART4
Serial serial4;
void UART4_IRQHandler( void )
{
    _uartIsr( &serial4 );
}
#endif
#ifdef BSP_USING_UART5
Serial serial5;
void UART5_IRQHandler( void )
{
    _uartIsr( &serial5 );
}
#endif

/*
static int _serialInit(Serial *serial, UART_HandleTypeDef *huart)
{
    rkfifo_init(&serial->_rxFifo, serial->_pRxBuff, sizeof(serial->_pRxBuff), 1);
    rkfifo_init(&serial->_txFifo, serial->_pTxBuff, sizeof(serial->_pTxBuff), 1);

#ifdef BSP_UART_USING_DMA
    serial->_dmarx_remaining_cnt = sizeof(serial->_pRxBuff);
    if (HAL_UART_Receive_DMA(serial->huart, serial->_rxFifo.data, sizeof(serial->_rxFifo)) != HAL_OK)
    {
        Error_Handler();
    }
    CLEAR_BIT(serial->huart->Instance->CR3, USART_CR3_EIE);
    __HAL_UART_ENABLE_IT(serial->huart, UART_IT_IDLE);
#endif

    serial->huart = huart;
    __HAL_UART_ENABLE_IT(serial->huart, UART_IT_RXNE);

    return 0;
}

static int _serialDeinit(Serial *serial)
{
    assert_param(serial != 0);
    __HAL_UART_DISABLE_IT(serial->huart, UART_IT_RXNE);

    return 0;
}
*/
/**
 * @brief 串口发送数据，非阻塞式发送
 *
 * @param serial 串口对象
 * @param pTxData 发送数据指针
 * @param txLen 要发送长度
 * @return uint32_t 发送成功字节数
 */
uint32_t bspSerialWrite( Serial *serial, const uint8_t *pTxData, uint32_t txLen )
{
    uint32_t ret = 0;

    ret = rkfifo_in( &serial->_txFifo, pTxData, txLen );

    if ( ret )
    {
        __HAL_UART_ENABLE_IT( serial->huart, UART_IT_TXE );
    }

    return ret;
}

int bspSerialReadReady( Serial *serial, uint32_t timeOut )
{
    int ret = 0;

    return ret;
}

int bspSerialWriteDone( Serial *serial, uint32_t timeOut )
{
    int ret = 0;
    return ret;
}

/**
 * @brief 串口读取数据
 *
 * @param serial 串口对象
 * @param pRxData 读取数据指针
 * @param rxLen 要读取长度
 * @return uint32_t 读取成功字节数
 */
uint32_t bspSerialRead( Serial *serial, uint8_t *pRxData, uint32_t rxLen )
{
    uint32_t rnum = rkfifo_out( &serial->_rxFifo, pRxData, rxLen );
    return rnum;
}

static inline int _stm32_getc( Serial *serial )
{
    int ch = -1;
    UART_HandleTypeDef *handle = serial->huart;
    if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_RXNE ) != RESET )
    {
        ch = handle->Instance->DR & 0xff;
    }
    return ch;
}

static inline int _stm32_putc( Serial *serial, uint8_t ch )
{
    UART_HandleTypeDef *handle = serial->huart;

    while ( __HAL_UART_GET_FLAG( handle, UART_FLAG_TC ) == RESET )
        ;
    serial->huart->Instance->DR = ch;
    return 0;
}

static int _serialRxneIsrCallback( Serial *serial )
{
    int ret = 0;
    int ch = _stm32_getc( serial );
    if ( ch != -1 && serial )
    {
        uint8_t c = ch & 0xff;
        ret = rkfifo_in( &serial->_rxFifo, &c, 1 );
    }
    return ret;
}

static int _serialTxeIsrCallback( Serial *serial )
{
    int ret = 0;

    uint8_t c;
    if ( rkfifo_out( &serial->_txFifo, &c, 1 ) )
    {
        _stm32_putc( serial, c );
        ret = 1;
    }

    return ret;
}

static int _serialTcIsrCallback( Serial *serial )
{
    int ret = 0;

    return ret;
}

#ifdef BSP_UART_USING_DMA
static void _serialDmaRecvIsr( Serial *serial )
{
}
#endif


void _uartIsr( Serial *serial )
{
    UART_HandleTypeDef *handle = serial->huart;

    if ( ( __HAL_UART_GET_FLAG( handle, UART_FLAG_RXNE ) != RESET ) &&
         ( __HAL_UART_GET_IT_SOURCE( handle, UART_IT_RXNE ) != RESET ) )
    {
        _serialRxneIsrCallback( serial );
        __HAL_UART_CLEAR_FLAG( handle, UART_FLAG_RXNE );
    }
    else if ( ( __HAL_UART_GET_FLAG( handle, UART_FLAG_TXE ) != RESET ) &&
              ( __HAL_UART_GET_IT_SOURCE( handle, UART_IT_TXE ) ) != RESET )
    {
        int ret = _serialTxeIsrCallback( serial );
        if ( ret == 0 )
        {
            __HAL_UART_DISABLE_IT( serial->huart, UART_IT_TXE );
            __HAL_UART_ENABLE_IT( serial->huart, UART_IT_TC );
        }
        __HAL_UART_CLEAR_FLAG( handle, UART_IT_TXE );
    }
    else if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_TC ) &&
              ( __HAL_UART_GET_IT_SOURCE( handle, UART_IT_TC ) != RESET ) )
    {
        _serialTcIsrCallback( serial );
        __HAL_UART_CLEAR_FLAG( handle, UART_IT_TC );
        __HAL_UART_DISABLE_IT( handle, UART_IT_TC );
    }
    else
    {
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_ORE ) != RESET )
        {
            __HAL_UART_CLEAR_OREFLAG( handle );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_NE ) != RESET )
        {
            __HAL_UART_CLEAR_NEFLAG( handle );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_FE ) != RESET )
        {
            __HAL_UART_CLEAR_FEFLAG( handle );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_PE ) != RESET )
        {
            __HAL_UART_CLEAR_PEFLAG( handle );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_IDLE ) != RESET )
        {
            __HAL_UART_CLEAR_IDLEFLAG( handle );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_CTS ) != RESET )
        {
            __HAL_UART_CLEAR_FLAG( handle, UART_FLAG_CTS );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_TXE ) != RESET )
        {
            __HAL_UART_CLEAR_FLAG( handle, UART_FLAG_TXE );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_TC ) != RESET )
        {
            __HAL_UART_CLEAR_FLAG( handle, UART_FLAG_TC );
        }
        if ( __HAL_UART_GET_FLAG( handle, UART_FLAG_RXNE ) != RESET )
        {
            __HAL_UART_CLEAR_FLAG( handle, UART_FLAG_RXNE );
        }
    }
}

void bspSerialInit( void )
{
#ifdef BSP_USING_UART1
    extern UART_HandleTypeDef huart1;
    _serialInit( &serial1, &huart1 );
#endif
#ifdef BSP_USING_UART2
    extern UART_HandleTypeDef huart2;
    _serialInit( &serial2, &huart2 );
#endif
#ifdef BSP_USING_UART3
    extern UART_HandleTypeDef huart3;
    _serialInit( &serial3, &huart3 );
#endif
#ifdef BSP_USING_UART4
    extern UART_HandleTypeDef huart4;
    _serialInit( &serial4, &huart4 );
#endif
#ifdef BSP_USING_UART5
    extern UART_HandleTypeDef huart5;
    _serialInit( &serial5, &huart5 );
#endif
}
