/******************************************************************************
 * @file     llsi.h
 * @version  V3.00
 * @brief    NUC1262 series LLSI driver header file
 *
 * @note
 * @copyright SPDX-License-Identifier: Apache-2.0
 * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __LLSI_H__
#define __LLSI_H__

#ifdef __cplusplus
extern "C"
{
#endif


/** @addtogroup Standard_Driver Standard Driver
  @{
*/

/** @addtogroup LLSI_Driver LLSI Driver
  @{
*/

/** @addtogroup LLSI_EXPORTED_STRUCTS LLSI Exported Structs
  @{
*/
typedef struct
{
    uint32_t u32BusClock;            /*!< Bus clock */
    uint32_t u32TransferTimeNsec;    /*!< Transfer time in nano second */
    uint32_t u32T0HTimeNsec;         /*!< T0H time in nano second */
    uint32_t u32T1HTimeNsec;         /*!< T1H time in nano second */
    uint32_t u32ResetTimeNsec;       /*!< Reset time in nano second */
} S_LLSI_TIME_INFO_T;

/*@}*/ /* end of group LLSI_EXPORTED_STRUCTS */

/** @addtogroup LLSI_EXPORTED_CONSTANTS LLSI Exported Constants
  @{
*/

/* LLSI Mode */
#define LLSI_MODE_SW                 (0 << LLSI_CTL_LLSIMODE_Pos)   /*!< Software mode */
#define LLSI_MODE_PDMA               (1 << LLSI_CTL_LLSIMODE_Pos)   /*!< PDMA mode */

/* LLSI Output Format */
#define LLSI_FORMAT_RGB              (0 << LLSI_CTL_OFDEF_Pos)      /*!< Output RGB format */
#define LLSI_FORMAT_GRB              (1 << LLSI_CTL_OFDEF_Pos)      /*!< Output GRB format */

/* LLSI Idle Output State */
#define LLSI_IDLE_LOW                (0 << LLSI_OCTL_IDOS_Pos)      /*!< Idle output low */
#define LLSI_IDLE_HIGH               (1 << LLSI_OCTL_IDOS_Pos)      /*!< Idle output high */

/* LLSI Interrupt Mask */
#define LLSI_UNDFL_INT_MASK          (0x001)                        /*!< Underflow interrupt mask */
#define LLSI_FEND_INT_MASK           (0x002)                        /*!< Frame end interrupt mask */
#define LLSI_RST_INT_MASK            (0x004)                        /*!< Reset command interrupt mask */
#define LLSI_EMP_INT_MASK            (0x008)                        /*!< FIFO empty interrupt mask */
#define LLSI_FUL_INT_MASK            (0x010)                        /*!< FIFO full interrupt mask */
#define LLSI_TXTH_INT_MASK           (0x020)                        /*!< TX threshold interrupt mask */

/*@}*/ /* end of group LLSI_EXPORTED_CONSTANTS */


/** @addtogroup LLSI_EXPORTED_FUNCTIONS LLSI Exported Functions
  @{
*/

/**
  * @brief      Set LLSI last data flag.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set LADF (LLSI_STATUS[8]) to set LLSI last data flag.
  */
#define LLSI_SET_LAST_DATA_FLAG(llsi)   ((llsi)->STATUS |= LLSI_STATUS_LADF_Msk)

/**
  * @brief      Get the TX FIFO empty flag.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @retval     0 TX FIFO is not empty.
  * @retval     1 TX FIFO is empty.
  * @details    Read EMPIF bit of LLSI_STATUS register to get the TX FIFO empty flag.
  */
#define LLSI_GET_TX_FIFO_EMPTY_FLAG(llsi)   (((llsi)->STATUS & LLSI_STATUS_EMPIF_Msk) >> LLSI_STATUS_EMPIF_Pos)

/**
  * @brief      Get the TX FIFO full flag.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @retval     0 TX FIFO is not full.
  * @retval     1 TX FIFO is full.
  * @details    Read FULIF bit of LLSI_STATUS register to get the TX FIFO full flag.
  */
#define LLSI_GET_TX_FIFO_FULL_FLAG(llsi)   (((llsi)->STATUS & LLSI_STATUS_FULIF_Msk) >> LLSI_STATUS_FULIF_Pos)

/**
  * @brief      Write datum to DATA register.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @param[in]  u32TxData The datum which user attempt to transfer through LLSI bus.
  * @return     None.
  * @details    Write u32TxData to LLSI_DATA register.
  */
#define LLSI_WRITE_DATA(llsi, u32TxData)   ((llsi)->DATA = (u32TxData))

/**
  * @brief      Set LLSI idle low.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Clear IDOS (LLSI_OCTL[0]) to set LLSI idle low.
  */
#define LLSI_SET_IDLE_LOW(llsi)   ((llsi)->OCTL &= ~LLSI_OCTL_IDOS_Msk)

/**
  * @brief      Set LLSI idle high.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set IDOS (LLSI_OCTL[0]) to set LLSI idle high.
  */
#define LLSI_SET_IDLE_HIGH(llsi)   ((llsi)->OCTL |= LLSI_OCTL_IDOS_Msk)

/**
  * @brief      Set LLSI RGB format.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Clear OFDEF (LLSI_CTL[12]) to set LLSI RGB format.
  */
#define LLSI_SET_RGB_FORMAT(llsi)   ((llsi)->CTL &= ~LLSI_CTL_OFDEF_Msk)

/**
  * @brief      Set LLSI GRB format.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set OFDEF (LLSI_CTL[12]) to set LLSI GRB format.
  */
#define LLSI_SET_GRB_FORMAT(llsi)   ((llsi)->CTL |= LLSI_CTL_OFDEF_Msk)

/**
  * @brief      Set LLSI software mode.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Clear LLSIMODE (LLSI_CTL[8]) to set LLSI software mode.
  */
#define LLSI_SET_SW_MODE(llsi)   ((llsi)->CTL &= ~LLSI_CTL_LLSIMODE_Msk)

/**
  * @brief      Set LLSI PDMA mode.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set LLSIMODE (LLSI_CTL[8]) to set LLSI PDMA mode.
  */
#define LLSI_SET_PDMA_MODE(llsi)   ((llsi)->CTL |= LLSI_CTL_LLSIMODE_Msk)

/**
  * @brief      Enable LLSI reset command function.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set RSTCEN (LLSI_CTL[1]) to enable LLSI reset command function.
  */
#define LLSI_ENABLE_RESET_COMMAND(llsi)   ((llsi)->CTL |= LLSI_CTL_RSTCEN_Msk)

/**
  * @brief      Disable LLSI reset command function.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Clear RSTCEN (LLSI_CTL[1]) to disable LLSI reset command function.
  */
#define LLSI_DISABLE_RESET_COMMAND(llsi)   ((llsi)->CTL &= ~LLSI_CTL_RSTCEN_Msk)

/**
  * @brief      Enable LLSI controller.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Set LLSIEN (LLSI_CTL[0]) to enable LLSI controller.
  */
#define LLSI_ENABLE(llsi)   ((llsi)->CTL |= LLSI_CTL_LLSIEN_Msk)

/**
  * @brief      Disable LLSI controller.
  * @param[in]  llsi The pointer of the specified LLSI module.
  * @return     None.
  * @details    Clear LLSIEN (LLSI_CTL[0]) to disable LLSI controller.
  */
#define LLSI_DISABLE(llsi)   ((llsi)->CTL &= ~LLSI_CTL_LLSIEN_Msk)



/* Function prototype declaration */
void LLSI_Open(LLSI_T *llsi, uint32_t u32LLSIMode, uint32_t u32OutputFormat, uint32_t u32BusClock, uint32_t u32TransferTimeNsec, uint32_t u32T0HTimeNsec, uint32_t u32T1HTimeNsec, uint32_t u32ResetTimeNsec, uint32_t u32PCNT, uint32_t u32IDOS);
void LLSI_Close(LLSI_T *llsi);
void LLSI_GetTimeInfo(LLSI_T *llsi, S_LLSI_TIME_INFO_T *sPt);
void LLSI_SetFIFO(LLSI_T *llsi, uint32_t u32TxThreshold);
void LLSI_EnableInt(LLSI_T *llsi, uint32_t u32Mask);
void LLSI_DisableInt(LLSI_T *llsi, uint32_t u32Mask);
uint32_t LLSI_GetIntFlag(LLSI_T *llsi, uint32_t u32Mask);
void LLSI_ClearIntFlag(LLSI_T *llsi, uint32_t u32Mask);


/*@}*/ /* end of group LLSI_EXPORTED_FUNCTIONS */

/*@}*/ /* end of group LLSI_Driver */

/*@}*/ /* end of group Standard_Driver */

#ifdef __cplusplus
}
#endif

#endif //__LLSI_H__
