/*
 * @file hv_drv_uart.h
 * @brief Header file of misc module.
 *
 * @verbatim
 * ==============================================================================
 *                        ##### How to use #####
 * ==============================================================================
 * (+) Use ()
 *
 * @endverbatim
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2023-06-14
 */

/** @file
 *  @brief UART DRV APIs
*/

#ifndef _HV_DRV_UART_H
#define _HV_DRV_UART_H


#include "hv_cal_Dma.h"

/** @defgroup DRV_UART DRV_UART
 *  hal uart functions
 *  @{
 */

/* Parity setting */
typedef enum _UartParity
{
    /* uart has no parity bit */
    UART_PARITY_NONE,
    /* uart has even parity bit */
    UART_PARITY_EVEN,
    /* uart has odd parity bit */
    UART_PARITY_ODD,
} UartParity;

/* Stop bit setting */
typedef enum _UartStopBit
{
    /* uart stop bit is 1 bit */
    UART_STOPBIT_1,
    /* uart stop bit is 1.5 bits or 2 bits */
    UART_STOPBIT_1_5_OR_2,
} UartStopBit;

/* Word length setting */
typedef enum _UartWordLen
{
    /* uart word length is 5 bits */
    UART_WORDLEN_5,
    /* uart word length is 6 bits */
    UART_WORDLEN_6,
    /* uart word length is 7 bits */
    UART_WORDLEN_7,
    /* uart word length is 8 bits */
    UART_WORDLEN_8,
} UartWordLen;

/* RX trigger */
typedef enum _UartRxTrigger
{
    /* 1 character in FIFO */
    UART_RX_FIFO_CHAR_1,
    /* FIFO 1/4 full */
    UART_RX_FIFO_QUARTER_FULL,
    /* FIFO 1/2 full */
    UART_RX_FIFO_HALF_FULL,
    /* FIFO 2 less than full */
    UART_RX_FIFO_FULL_2,
} UartRxTrigger;

/* TX trigger */
typedef enum _UartTxTrigger
{
    /* FIFO empty */
    UART_TX_FIFO_EMPTY,
    /* 2 characters in FIFO */
    UART_TX_FIFO_CHAR_2,
    /* FIFO 1/4 full */
    UART_TX_FIFO_QUARTER_FULL,
    /* FIFO 1/2 full */
    UART_TX_FIFO_HALF_FULL,
} UartTxTrigger;

/* UART error codes */
typedef enum _UartError
{
    /* No error            */
    UART_ERROR_NONE =      ((UINT32)0x00),
    /* Parity error        */
    UART_ERROR_PE =        ((UINT32)0x01),
    /* Receiver fifo error */
    UART_ERROR_RFE =       ((UINT32)0x02),
    /* frame error         */
    UART_ERROR_FE =        ((UINT32)0x04),
    /* Overrun error       */
    UART_ERROR_ORE =       ((UINT32)0x08),
    /* DMA transfer error  */
    UART_ERROR_DMA =       ((UINT32)0x10),
    /* Break Interrupt     */
    UART_ERROR_BI =        ((UINT32)0x20),
} UartError;

/* HAL UART State structures definition */
typedef enum _UartStateType
{
    /* Peripheral is not initialized                      */
    UART_STATE_RESET             = 0x00,
    /* Peripheral Initialized and ready for use           */
    UART_STATE_READY             = 0x01,
    /* an internal process is ongoing                     */
    UART_STATE_BUSY              = 0x02,
    /* Data Transmission process is ongoing               */
    UART_STATE_BUSY_TX           = 0x12,
    /* Data Reception process is ongoing                  */
    UART_STATE_BUSY_RX           = 0x22,
    /* Data Transmission and Reception process is ongoing */
    UART_STATE_BUSY_TX_RX        = 0x32,
    /* Timeout state                                      */
    UART_STATE_TIMEOUT           = 0x03,
    /* Error                                              */
    UART_STATE_ERROR             = 0x04
} UartStateType;

/* UART port enum */
typedef enum _UartPortIndex
{
    UART_PORT_0 = 0,
    UART_PORT_1,
    UART_PORT_MAX
} UartPortIndex;

typedef enum _UartCallbackType
{
    UART_INT_TX_COMPLETE,
    UART_INT_RX_COMPLETE,
    UART_DMA_TX_COMPLETE,
    UART_DMA_RX_COMPLETE,
} UartCallbackType;

typedef void (*UART_CALLBACK)(UartCallbackType enType, void *pArg, UCHAR8 ucSize);

typedef struct _UartInitParam
{
    UartPortIndex   enPort;
    UINT32          uiBaudrate;
    UINT32          uiPriority;
    UartParity      enParity;
    UartStopBit     enStopbit;
    UartWordLen     enWordlen;
    BOOL            bFifoEnable;
    BOOL            b9BitMode;
    BOOL            bNewInterface;
    UartRxTrigger   enRxFiFoTrig;
    UartTxTrigger   enTxFiFoTrig;
    UART_CALLBACK   fCallback;

    void            *pCallbackArg;
} UartInitParam;

/* UART data structure */
typedef struct _UartSelf UartSelf;

void Hv_Drv_Uart_SetDmaTx(UartSelf *pstSelf, DmaSelf *pstHdmaTx);

void Hv_Drv_Uart_SetDmaRx(UartSelf *pstSelf, DmaSelf *pstHdmaRx);

/** Initialize uart
 *  @param initParam pointer to uart configure parameters
 *  @return uart structure pointer
 */
UartSelf *Hv_Drv_Uart_Init(UartInitParam *pstInitParam);

/** brief De-initialize uart
 *  @param self uart pointer
 */
void Hv_Drv_Uart_Cleanup(UartSelf *pstSelf);

/** brief De-initialize uart
 *  @param self uart pointer
 */
void Hv_Drv_Uart_CleanFifo(UartSelf *pstSelf);

/** Detection baudrate of uart
 *  @param port uart port
 *  @param baudrate detection baudrate value
 *  @return result
 */
Status Hv_Drv_Uart_BaudrateDetection(UartPortIndex enPort, UINT32 *puiBaudrate);

/** Set baudrate of uart
 *  @param self uart pointer
 *  @param baudrate baudrate
 *  @return result
 */
Status Hv_Drv_Uart_SetBaudrate(UartSelf *pstSelf, UINT32 uiBaudrate);

/** Set serial format of homebus
 *  @param self uart pointer
 *  @param parity parity
 *  @param stopbit stop bit
 *  @param wordlen word length
 *  @return result
 */
Status Hv_Drv_Uart_SetFormat(UartSelf *pstSelf, UartParity enParity, UartStopBit enStopbit, UartWordLen enWordlen);

/** Receives an amount of data in polling mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be received
 *  @param timeout timeout duration ms
 *  @return result
 */
Status Hv_Drv_Uart_Receive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout);
/** enable uart receive int��
 *  @param ucPort uart port
 *  @return result
 */
Status Hv_Drv_Uart_EnableReceive(UCHAR8 ucPort);

/** Receives an amount of data in blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be received
 *  @return result
 */
Status Hv_Drv_Uart_BlockReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize);


/** Receives an amount of data in non blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be received
 *  @return result
 */
Status Hv_Drv_Uart_IntReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize);

/** Receives an amount of data in non blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be received
 *  @return result
 */
Status Hv_Drv_Uart_DmaReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize);

/** Get character by UART
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @return result
 */
Status Hv_Drv_Uart_GetChar(UartSelf *pstSelf, UCHAR8 *pucData);

/** Output address by UART with 9bit mode
 *  @param self uart pointer
 *  @param data device address
 *  @return result
 */
Status Hv_Drv_Uart_PutAddr(UartSelf *pstSelf, UCHAR8 ucAddr);

/** Output character by UART
 *  @param self uart pointer
 *  @param data outputed character
 *  @return result
 */
Status Hv_Drv_Uart_PutChar(UartSelf *pstSelf, UCHAR8 ucData);

/** Sends an amount of data in blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be sent
 *  @param timeout timeout duration ms
 *  @return result
 */
Status Hv_Drv_Uart_Transmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout);

/** Sends an amount of data
 *  @param ucPort uart port
 *  @param data pointer to data buffer
 *  @param size amount of data to be sent
 *  @return result
 */
Status Hv_Drv_Uart_Send(UCHAR8 ucPort, const UCHAR8 *pucData, USHORT16 usSize);

/** Sends an amount of data in non blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be sent
 *  @return result
 */
Status Hv_Drv_Uart_IntTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize);

/** Sends an amount of data in non blocking mode
 *  @param self uart pointer
 *  @param data pointer to data buffer
 *  @param size amount of data to be sent
 *  @return result
 */
Status Hv_Drv_Uart_DmaTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize);

/** Get errorCode of uart
 *  @param self uart pointer
 *  @return errorCode result
 */
UINT32 Hv_Drv_Uart_GetErrorCode(UartSelf *pstSelf);

/** Get empty of uart
 *  @param self uart pointer
 *  @return result empty or not
 */
BOOL Hv_Drv_Uart_IsEmpty(UartSelf *pstSelf);

/**
 * @brief uart enable for log.
  * @param[in] bEnble: on/off
 */
VOID Hv_Drv_EnableUart(BOOL bEnble);

/** @} */

#endif




