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

#ifndef _HV_CAL_I2C_H
#define _HV_CAL_I2C_H

#include "hv_cal_Dma.h"

#define I2C_FLAG_RESTART_DEF                    ((UINT32)0x00001000)
#define I2C_FLAG_MASTER_ON_HOLD                 ((UINT32)0x00002000)
#define I2C_FLAG_STUCK_AT_LOW                   ((UINT32)0x00004000)
#define I2C_FLAG_MASK                           ((UINT32)0x00007FFF)

typedef enum _I2cPort
{
    I2C_PORT_0 = 0,
    I2C_PORT_1,
    I2C_PORT_MAX
} I2cPort;

typedef enum _I2cMode
{
    I2C_MODE_NONE = 0,
    I2C_MODE_MASTER,
    I2C_MODE_SLAVE,
    I2C_MODE_MEM
} I2cMode;

typedef enum _I2cSpeed
{
    I2C_SPEED_50K = 0,
    I2C_SPEED_80K,
    I2C_SPEED_100K,
    I2C_SPEED_200K,
    I2C_SPEED_400K,
} I2cSpeed;

typedef enum _I2cTransType
{
    I2C_MASTER_TRANSMIT = 0,
    I2C_MASTER_RECEIVE,
    I2C_SLAVE_TRANSMIT,
    I2C_SLAVE_RECEIVE,
    I2C_SLAVE_STOP,
    I2C_SLAVE_RESTART,
    I2C_ABRT_TRANSMIT,
} I2cTransType;

typedef enum _I2cState
{
    /*!< Peripheral is not yet Initialized */
    I2C_STATE_RESET = 0,
    /*!< Peripheral Initialized and ready for use  */
    I2C_STATE_READY,
    /*!< An internal process is ongoing */
    I2C_STATE_BUSY,
    /*!< Data Transmission process is ongoing */
    I2C_STATE_BUSY_TX,
    /*!< Data Reception process is ongoing */
    I2C_STATE_BUSY_RX,
    /*!< Data Transmission command and reception datas process is ongoing */
    I2C_STATE_BUSY_TXRX,
    /*!< slave get restart signal*/
    I2C_STATE_BUSY_SLAVE_RESTART,
    /*!< Timeout state  */
    I2C_STATE_TIMEOUT,
     /*!< Error*/
    I2C_STATE_ERROR
} I2cState;

typedef enum _I2cErrType
{
    /*!< No error             */
    I2C_ERROR_NONE = 0,
    /*!< BERR error           */
    I2C_ERROR_BERR,
    /*!< ARLO error           */
    I2C_ERROR_ARLO,
    /*!< AF error             */
    I2C_ERROR_AF,
    /*!< OVR error            */
    I2C_ERROR_OVR,
    /*!< DMA error            */
    I2C_ERROR_DMA,
    /*!< Timeout error        */
    I2C_ERROR_TIMEOUT
} I2cErrType;

typedef enum _I2cTransComplete
{
    I2C_TRANS_IN_PROCESS = 0,
    I2C_TRANS_END,
} I2cTransComplete;


typedef enum _I2cAddrBits
{
    I2C_ADDR_7BIT = 0,
    I2C_ADDR_10BIT,
} I2cAddrBits;

typedef Status (*Hv_I2C_CpltCallbackType)(I2cTransType enTransType, void *pvArg);

typedef struct _I2cInitParam
{
    /*!< I2C port, 1 or 2 */
    I2cPort enPort;
    /*!< Specifies i2c as master or slave*/
    I2cMode enMode;
    /*!< Specifies the clock frequency.This parameter must be set to a value lower than 400kHz */
    I2cSpeed enSpeed;
    /*!< Specifies the first device own address.*/
    UINT32 OwnAddress;
    /*!< Specifies if 7-bit or 10-bit addressing mode is selected.*/
    I2cAddrBits enAddressingMode;
    /* new interface for slave int receive mode. */
    BOOL bNewInterface;
    Hv_I2C_CpltCallbackType fI2cCpltCallback;
} I2cInitParam;

typedef struct _HvCalI2c
{
    /*!< I2C communication parameters */
    I2cInitParam     enInitParam;
    /*!< Pointer to I2C transfer buffer */
    UCHAR8          *pucCmdAddr;
    /*!< I2C transfer usSize */
    USHORT16        usCmdAddrSize;
    /*!< Pointer to I2C transfer buffer */
    UCHAR8          *pucTxBuff;
    /*!< I2C transfer usSize */
    USHORT16        usTxferSize;
    /*!< I2C transfer usSize */
    USHORT16        usTxferCount;
    /*!< Pointer to I2C transfer buffer */
    UCHAR8          *pucRxBuff;
    /*!< I2C transfer usSize */
    USHORT16        usRxferSize;
    /*!< I2C transfer usCount */
    USHORT16        usRxferCount;

    /*!< I2C communication state*/
    I2cState        enState;
    UCHAR8          ucInitCount;
    /*!< I2C Error code*/
    I2cErrType      enErrorCode;
    UINT32          uiBaseOffset;
    I2cTransComplete    enTransCompleteFlag;
    DmaSelf*            hdmaTx;
    DmaSelf*            hdmaRx;
} HvCalI2c;

typedef struct _I2cFuncParam
{
    USHORT16 usDevAddress;
    UCHAR8 *pucCmdAddr;
    USHORT16 usCmdAddrSize;
    UCHAR8 *pucData;
    USHORT16 usDataSize;
} I2cFuncParam;


/** @defgroup CAL_I2C CAL_I2C
 *  cal i2c functions
 *  @{
 */

/** Initialize i2c
 *  @param pstInitParam pointer to i2c configuration parameters
 *  @return i2c handler
 */
HvCalI2c*  Hv_Cal_I2C_Init(I2cInitParam *pstInitParam);

/** Set i2c transfer speed
 *  @param pstSelf i2c handler
 *  @param enI2cSpeed i2c transfer speed
 */
void Hv_Cal_I2C_Setpeed(HvCalI2c *pstSelf, I2cSpeed enI2cSpeed );


/** De-initialize i2c
 *  @param pstSelf i2c handler
 *  @return result
 */
Status Hv_Cal_I2C_Cleanup(HvCalI2c *pstSelf);

void I2C_SetDmaTx(HvCalI2c *self, DmaSelf *hdmaTx);
void I2C_SetDmaRx(HvCalI2c *self, DmaSelf *hdmaRx);

USHORT16 Hv_Cal_I2C_GetRxDataCount(HvCalI2c *pstSelf);

/** Transmits in master mode an amount of data in blocking mode.
 *  @param pstSelf i2c handler
 *  @param pstParam target device address
 *  pointer to command data buffer
 *  command length
 *  pointer to data buffer to be transmited
 *  amount of data to be sent
 *  @param uiTimeout uiTimeout duration
  * @retval Status
 */
Status Hv_Cal_I2C_MasterPollingTransmit(HvCalI2c *pstSelf, I2cFuncParam *pstParam, UINT32 uiTimeout);

/** Transmit in master mode an amount of data in non-blocking mode with interrupt
 *  @param pstSelf i2c handler
 *  @param pstParam target device address
 *  pointer to command data buffer
 *  command length
 *  pointer to data buffer to be transmited
 *  amount of data to be sent
  * @retval Status
 */
Status Hv_Cal_I2C_MasterIntTransmit(HvCalI2c  *pstSelf, I2cFuncParam *pstParam);

/** Transmit in master mode an amount of data in non-blocking mode with DMA
 *  @param self i2c handler
 *  @param devAddress target device address
 *  @param pData pointer to data buffer to be transmited
 *  @param size amount of data to be sent
  * @retval HAL status
 */
Status Hv_Cal_I2C_MasterDmaTransmit(HvCalI2c  *self, USHORT16 devAddress, UCHAR8* pData, USHORT16 dataSize);

/** Receives in master mode an amount of data in blocking mode.
 *  @param pstSelf i2c handler
 *  @param pstParam target device address
 *  pointer to command data buffer
 *  command length
 *  pointer to data buffer to be receive
 *  amount of data to be receive
 *  @param uiTimeout uiTimeout duration
 *  @retval Status
*/
Status Hv_Cal_I2C_MasterPollingReceive(HvCalI2c *pstSelf,I2cFuncParam *pstParam, UINT32 uiTimeout);

/** Receive in master mode an amount of data in non-blocking mode with interrupt
 *  @param pstSelf i2c handler
 *  @param pstParam target device address
 *  pointer to command data buffer
 *  command length
 *  pointer to data buffer to be receive
 *  amount of data to be receive
 *  @retval Status
*/
Status Hv_Cal_I2C_MasterIntReceive(HvCalI2c *pstSelf, I2cFuncParam *pstParam);

/** Receive in master mode an amount of data in non-blocking mode with DMA
 *  @param self i2c handler
 *  @param devAddress target device address
 *  @param pCmd pointer to command data buffer
 *  @param cmdSize command length
 *  @param pData pointer to data buffer to be transmited
 *  @param dataSize amount of data to be sent
 *  @retval HAL status
*/
Status Hv_Cal_I2C_MasterDmaReceive(HvCalI2c *self, USHORT16 devAddress, UCHAR8 *pCmdAddr, USHORT16 cmdAddrSize, UCHAR8* pRxData, USHORT16 dataSize);

/** Transmits in slave mode an amount of data in blocking mode.
 *  @param pstSelf i2c handler
 *  @param pucData pointer to data buffer
 *  @param usSize amount of data to be sent
 *  @param uiTimeout uiTimeout duration
 *  @retval Status
 */
Status Hv_Cal_I2C_SlavePollingTransmit(HvCalI2c *pstSelf, UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout);

/** Transmit in slave mode an amount of data in non-blocking mode with interrupt
 *  @param pstSelf i2c handler
 *  @param pucData pointer to data buffer
 *  @param usSize amount of data to be sent
 *  @retval Status
 */
Status Hv_Cal_I2C_SlaveIntTransmit(HvCalI2c *pstSelf, UCHAR8 *pucData, USHORT16 usSize);

/** Transmit in slave mode an amount of data in non-blocking mode with DMA  
 *  @param self i2c handler
 *  @param pData pointer to data buffer
 *  @param dataSize amount of data to be sent
 *  @retval HAL status
 */
Status Hv_Cal_I2C_SlaveDmaTransmit(HvCalI2c  *self, UCHAR8* pData, USHORT16 dataSize);

/** Receive in slave mode an amount of data in blocking mode
 *  @param pstSelf i2c handler
 *  @param pucData pointer to data buffer
 *  @param usSize amount of data to be sent
 *  @param uiTimeout uiTimeout duration
 *  @retval Status
 */
Status Hv_Cal_I2C_SlavePollingReceive(HvCalI2c *pstSelf, UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout);

/** Receive in slave mode an amount of data in non-blocking mode with interrupt
 *  @param pstSelf i2c handler
 *  @param pucData pointer to data buffer
 *  @param usSize amount of data to be sent
 *  @retval Status
 */
Status Hv_Cal_I2C_SlaveIntReceive(HvCalI2c *pstSelf, UCHAR8 *pucData);

/** enable Receive int in slave mode
 *  @param ucPort i2c port
 *  @retval Status
 */
Status Hv_Cal_I2C_SlaveIntReceiveEnable(UCHAR8 ucPort);

/** Transmit in slave mode an amount of data in non-blocking mode with interrupt
 *  @param ucPort i2c port
 *  @param pucData pointer to data buffer
 *  @param usSize amount of data to be sent
 *  @retval Status
 */
Status Hv_Cal_I2C_SlaveTransmit(UCHAR8 ucPort, UCHAR8 *pucData, USHORT16 usSize);

/** Receive in slave mode an amount of data in non-blocking mode with DMA
 *  @param self i2c handler
 *  @param pData pointer to data buffer
 *  @param dataSize amount of data to be sent
 *  @retval HAL status
 */
Status Hv_Cal_I2C_SlaveDmaReceive(HvCalI2c *self, UCHAR8* pData, USHORT16 dataSize);


/** Receive in slave mode an amount of data in non-blocking mode with interrupt
 *  @param pstSelf i2c handler
 *  @retval is or not
 */
BOOL Hv_Cal_I2C_TransferIsComplete(HvCalI2c *pstSelf);

/** config i2c clk direction.
 *  @param enMode master or slave
 *  @param enPort port number
 *  @retval null
 */
VOID Hv_Cal_I2C_InitPin(I2cMode enMode, I2cPort enPort);

/** @} */


#endif




