/**************************************************************************
 * @file     pan_uart.h
 * @version  V1.10
 * $Revision: 2 $
 * $Date:    2023/11/08  $  
 * @brief    Panchip series UART driver header file
 *
 * @note
 * Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/

#ifndef __PAN_UART_H__
#define __PAN_UART_H__

/**
 * @brief Uart Interface
 * @defgroup uart_interface Uart Interface
 * @{
 */
#ifdef __cplusplus
extern "C"
{
#endif

#include "pan271x.h"

/**@defgroup UART_TX_TRIG_FLAG Uart transmit fifo threshold 
 * @brief       Uart transmit fifo threshold definition
 * @{ */
typedef enum UART_TxTrigger
{
    UART_TX_FIFO_EMPTY              = 0x0,
    UART_TX_FIFO_TWO_CHARS          = 0x1,
    UART_TX_FIFO_THREE_CHARS        = 0x2,
    UART_TX_FIFO_FOUR_CHARS         = 0x3
} UART_TxTriggerDef;
/**@} */

/**@defgroup UART_RX_TRIG_FLAG Uart receive fifo threshold 
 * @brief       Uart receive fifo threshold definition
 * @{ */
typedef enum UART_RxTrigger
{
    UART_RX_FIFO_ONE_CHAR           = 0x0,
    UART_RX_FIFO_TWO_CHARS       	= 0x1,
    UART_RX_FIFO_THREE_CHARS        = 0x2,
    UART_RX_FIFO_FOUR_CHARS 		= 0x3
} UART_RxTriggerDef;
/**@} */


/**@defgroup UART_INT_FLAG Uart interrupts status 
 * @brief    These are the bit definitions used for managing UART interrupts.
 *  The functionality of ETBEI and ERBFI alters when programmable THRE
 *  interrupt mode is active (dw_uart_enablePtime()).  See the
 *  DW_apb_uart databook for a detailed description.
 * @{ */

typedef enum UART_Irq
{
	UART_IRQ_RX_TIMEOUT  		= UART_CTL_RX_TIMEOUT_INT_EN_Msk, // receive fifo timeout
    UART_IRQ_RX_NOT_EMPTY  		= UART_CTL_RX_NE_INT_EN_Msk,      // receive fifo not empty
    UART_IRQ_RX_OVERFLOW      	= UART_CTL_RX_OV_INT_EN_Msk,      // receive fifo overflow
    UART_IRQ_RX_ERROR    		= UART_CTL_RX_ERR_INT_EN_Msk,     // receive fifo error
    UART_IRQ_TX_NOT_FULL   		= UART_CTL_TX_NF_INT_EN_Msk,      // transmitter fifo not full
    UART_IRQ_ALL            	= 0x10e02      					  // all interrupts
} UART_IrqDef;
/**@} */


/**
 * @brief	 This function enables transmit FIFOs and function, if they are
 *  available.
 * @param  UARTx: where x can be 1, 2 to select the
 *         UART peripheral.
 * @retval None
 */
__STATIC_INLINE void UART_EnableTx(UART_T* UARTx)
{
    UARTx->UART_CTL |= UART_CTL_TX_EN_Msk;
}

/**
 * @brief	 This function disables transmit FIFOs and function.
 * @param  UARTx: where x can be 1, 2 to select the
 *         UART peripheral.
 * @retval None
 */

__STATIC_INLINE void UART_DisableTx(UART_T* UARTx)
{
    UARTx->UART_CTL &= ~UART_CTL_TX_EN_Msk;
}

/**
 * @brief	 This function enables receive FIFOs and function, if they are
 *  available.
 * @param  UARTx: where x can be 1, 2 to select the
 *         UART peripheral.
 * @retval None
 */
__STATIC_INLINE void UART_EnableRx(UART_T* UARTx)
{
    UARTx->UART_CTL |= UART_CTL_RX_EN_Msk;
}

/**
 * @brief	 This function disables receive FIFOs and function.
 * @param  UARTx: where x can be 1, 2 to select the
 *         UART peripheral.
 * @retval None
 */

__STATIC_INLINE void UART_DisableRx(UART_T* UARTx)
{
    UARTx->UART_CTL &= ~UART_CTL_RX_EN_Msk;
}


/**
	* @brief	Set the trigger level of the transmitter FIFO empty interrupt.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @param  level: Uart transmit fifo threshold \ref UART_TxTriggerDef
	* @return None
	*/
__STATIC_INLINE void UART_SetTxIntTrigger(UART_T* UARTx, UART_TxTriggerDef level)
{
	UARTx->UART_CTL = (UARTx->UART_CTL & ~UART_CTL_TX_NF_MASK_Msk) | (level << UART_CTL_TX_NF_MASK_Pos);
}


/**
	* @brief	Sets the trigger level of the receiver FIFO full interrupt.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @param  level: Uart receive fifo threshold \ref UART_RxTriggerDef
	* @return None
	*/
__STATIC_INLINE void UART_SetRxIntTrigger(UART_T* UARTx, UART_RxTriggerDef level)
{
    UARTx->UART_CTL = (UARTx->UART_CTL & ~UART_CTL_RX_NE_MASK_Msk) | (level << UART_CTL_RX_NE_MASK_Pos);
}

/**
	* @brief	Get the transmit fifo level.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return how many bytes deep the transmitter and receiver FIFOs are
	*/
__STATIC_INLINE uint8_t UART_GetTxFifoLevel(UART_T* UARTx)
{
    return (uint8_t)((UARTx->UART_CTL & UART_CTL_RX_NE_MASK_Msk) >> UART_CTL_TX_NF_MASK_Pos);
}

/**
	* @brief	Get the receive fifo level.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return the number of characters currently present in the Rx fifo.
	*/
__STATIC_INLINE uint8_t UART_GetRxFifoLevel(UART_T* UARTx)
{
     return (uint8_t)((UARTx->UART_CTL & UART_CTL_RX_NE_MASK_Msk) >> UART_CTL_RX_NE_MASK_Pos);
}


/**
  * @brief  uart send data function
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  Data: data need to seed
  * @retval None
  */
__STATIC_INLINE void UART_SendData(UART_T* UARTx, uint8_t Data)
{
    UARTx->UART_TXDATA = Data;
}

/**
  * @brief  uart receive data function
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval received data
  */
__STATIC_INLINE uint8_t UART_ReceiveData(UART_T* UARTx)
{
    return (uint8_t)UARTx->UART_RXDATA;
}


/**
  * @brief  enable interrupt,include Modem status linestatus,THRE,receive data
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  irq: interrupt type
  * @retval none
  */
__STATIC_INLINE void UART_EnableIrq(UART_T* UARTx, UART_IrqDef irq)
{
    UARTx->UART_CTL |= (irq & UART_IRQ_ALL);
}

/**
  * @brief  disable interrupt
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  irq: interrupt type
  * @retval none
  */
__STATIC_INLINE void UART_DisableIrq(UART_T* UARTx, UART_IrqDef irq)
{
    UARTx->UART_CTL &= ~(irq & UART_IRQ_ALL);
}

/**
  * @brief  check interrupt enable or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  irq: interrupt type
  * @retval none
  */
__STATIC_INLINE bool UART_IsIrqEnabled(UART_T* UARTx, UART_IrqDef irq)
{
    return (UARTx->UART_CTL & irq ) ? true : false;
}


/**
  * @brief  check tx fifo empty or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsTxFifoEmpty(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_TX_EMPTY_FLAG_Msk) ? true : false;
}

/**
  * @brief  check tx fifo full or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsTxFifoFull(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_TX_FULL_FLAG_Msk) ? true : false;
}

/**
  * @brief  check rx fifo empty or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsRxFifoEmpty(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_RX_EMPTY_FLAG_Msk) ? true : false;
}

/**
  * @brief  check tx busy or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsTxBusy(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_TX_BUSY_Msk) ? true : false;
}

/**
  * @brief  check rx timeout or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsRxTimeout(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_RX_TIMEOUT_FLAG_Msk) ? true : false;
}

/**
  * @brief  check rx fifo empty or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsRxNotEmpty(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_RX_NE_FLAG_Msk) ? true : false;
}

/**
  * @brief  check rx fifo full or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsRxFifoFull(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_RX_FULL_FLAG_Msk) ? true : false;
}


/**
	* @brief	Get the transmit fifo data number.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return how many bytes deep the transmitter FIFOs are
	*/
__STATIC_INLINE uint8_t UART_GetTxFifoDataNum(UART_T* UARTx)
{
    return (uint8_t)((UARTx->UART_STATUS & UART_STATUS_TX_FIFO_NUM_Msk) >> UART_STATUS_TX_FIFO_NUM_Pos);
}

/**
	* @brief	Get the receive fifo data number.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return the number of characters currently present in the Rx fifo.
	*/
__STATIC_INLINE uint8_t UART_GetRxFifoDataNum(UART_T* UARTx)
{
     return (uint8_t)((UARTx->UART_STATUS & UART_STATUS_RX_FIFO_NUM_Msk) >> UART_STATUS_RX_FIFO_NUM_Pos);
}

/**
  * @brief  check rx busy or not
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @retval true or false
  */
__STATIC_INLINE bool UART_IsRxBusy(UART_T* UARTx)
{
    return (UARTx->UART_STATUS & UART_STATUS_RX_BUSY_Msk) ? true : false;
}

/**
	* @brief  Timeout function enable.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return None.
	*/
__STATIC_INLINE void UART_EnableRxTimeout(UART_T* UARTx)
{
     UARTx->TIMEOUT_CTL |= TIMEOUT_CTL_TIMEOUT_EN_Msk;
}

/**
	* @brief  Set Timeout compare count.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @param  cnt: timeout cnt value
	* @return None.
	*/
__STATIC_INLINE void UART_SetRxTimeoutCnt(UART_T* UARTx, uint32_t cnt)
{
     UARTx->TIMEOUT_CTL = (UARTx->TIMEOUT_CTL & ~TIMEOUT_CTL_TIMEOUT_CNT_TOTAL_Msk) | (cnt << TIMEOUT_CTL_TIMEOUT_CNT_TOTAL_Pos);
}

/**
	* @brief  Get Timeout compare count.
	* @param  UARTx: where x can be 1, 2 to select the
	*         UART peripheral.
	* @return Timeout set value.
	*/
__STATIC_INLINE uint32_t UART_GetRxTimeoutCnt(UART_T* UARTx)
{
     return (UARTx->TIMEOUT_CTL & TIMEOUT_CTL_TIMEOUT_CNT_TOTAL_Msk) >> TIMEOUT_CTL_TIMEOUT_CNT_TOTAL_Pos;
}

/**
  * @brief  Initializes the UARTx peripheral according to the specified
  *         parameters in the UART_InitStruct .
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  UART_BaudRate: baud rate set value.
  * @return UART init success (true) or fail (false)
  */
extern bool UART_Init(UART_T* UARTx, uint32_t UART_BaudRate);
/**
  * @brief  Deinit the UARTx peripheral
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @return None
  */
extern void UART_DeInit(UART_T* UARTx );

/**
  * @brief  This function is used to send multiple data
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  Buf: pointer to send data storage location. 
  * @param  BufSize: used to indicate the offset of buf.
  * @param  SendSize: used to indicate the size need to send.     
  * @return Send success (true) or fail (false)
  */
extern bool UART_SendMultipleData(UART_T* UARTx, uint8_t* Buf, size_t BufSize, size_t SendSize);

/**
  * @brief  This function is used to receive multiple data
  * @param  UARTx: where x can be 1, 2 to select the
  *         UART peripheral.
  * @param  Buf: pointer to receive data storage location 
  * @param  BufSize: used to indicate the offset of buf
  * @param  ExpectSize: used to indicate the size expect to receive  
  * @return Receive success (true) or fail (false)
  */
extern bool UART_ReceiveMultipleData(UART_T* UARTx, uint8_t* Buf, size_t BufSize, size_t ExpectSize);


/**@} */

#ifdef __cplusplus
}
#endif

#endif //__PAN_UART_H__

/*** (C) COPYRIGHT 2023 Panchip Technology Corp. ***/








