/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2022. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

#ifndef _AC780X_I2C_H
#define _AC780X_I2C_H
/*!
 * @file ac780x_i2c.h
 *
 * @brief This file provides i2c integration functions interface.
 *
 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* ============================================  Includes  ============================================ */
#include "ac7802x.h"

/* ============================================  Define  ============================================ */
#define I2C_USE_INTERRUPT_TRANSMIT

/*!
* @brief I2C 10bit address reserve mask bit macro.
*/
#define I2C_ADDEXT_PRIMARY_BYTE_FIX (0xF8)

/*!
* @brief I2C hardware timeout count macro.
*/
#define I2C_HW_DEADLINE_TIMEOUT (0x80000UL)

/*!
* @brief I2C instance index macro.
*/
#define I2C_INDEX(I2Cx)    ((uint8_t)(((uint32_t)(I2Cx) - I2C0_BASE) >> 12U))

/*!
* @brief I2C hardware status macro.
*/
#define I2C_HW_STATUS_ERROR_NULL 0x00U               /*!< I2C hardware status : without error */
#define I2C_HW_STATUS_BUS_BUSY 0x01U                 /*!< I2C hardware status : bus busy */
#define I2C_HW_STATUS_NACK 0x02U                     /*!< I2C hardware status : get nack */
#define I2C_HW_STATUS_BND_TIMEOUT 0x04U              /*!< I2C hardware status : one byte transfer timeout error */
#define I2C_HW_STATUS_CORE_READY_TIMROUT 0x08U       /*!< I2C hardware status : wait ready timeout error */
#define I2C_HW_STATUS_START_TO_BUSY_TIMEOUT 0x10U    /*!< I2C hardware status : send start to busy timeout error */
#define I2C_HW_STATUS_STOP_TO_IDLE_TIMEOUT 0x20U     /*!< I2C hardware status : send stop to idle timeout error */

/*!
* @brief I2C application status macro.
*/
#define I2C_TRANSMIT_STATUS_ERROR_NULL 0x00U              /*!< I2C transmit status : without error */
#define I2C_TRANSMIT_STATUS_NOT_MATCH 0x01U               /*!< I2C transmit status : master addressing slave not match */
#define I2C_TRANSMIT_STATUS_MATCHED 0x02U                 /*!< I2C transmit status : slave get matched */
#define I2C_TRANSMIT_STATUS_NACK 0x04U                    /*!< I2C transmit status : get nack */
#define I2C_TRANSMIT_STATUS_FINISHED 0x08U                /*!< I2C transmit status : TX/RX transmit finished */
#define I2C_TRANSMIT_STATUS_TXUF 0x10U                    /*!< I2C transmit status : slave TX under flow */
#define I2C_TRANSMIT_STATUS_RXOF 0x20U                    /*!< I2C transmit status : slave RX over flow */
#define I2C_TRANSMIT_STATUS_ARBLOST 0x40U                 /*!< I2C transmit status : arbitration lost */
#define I2C_TRANSMIT_STATUS_START_FLAG 0x100U             /*!< I2C transmit status : get start flag */
#define I2C_TRANSMIT_STATUS_STOP_FLAG 0x200U              /*!< I2C transmit status : get stop flag */

/* ===========================================  Typedef  ============================================ */
/*!
* @brief I2C write/read enum
*/
typedef enum
{
    I2C_WRITE = 0x00U,      /*!< I2C write transfer */
    I2C_READ = 0x01U        /*!< I2C read transfer */
} I2C_WRType;

/*!
* @brief I2C ack/nack enum
*/
typedef enum
{
    I2C_ACK = 0x00U,        /*!< I2C send ack on next byte */
    I2C_NACK = 0x01U        /*!< I2C send nack on next byte */
} I2C_AckType;

/*!
* @brief I2C master/slave mode enum
*/
typedef enum
{
    I2C_SLAVE = 0x00U,      /*!< I2C slave mode */
    I2C_MASTER = 0x01U      /*!< I2C master mode */
} I2C_ModeType;

/*!
* @brief I2C configuration structure for master attribute
*
* This structure holds the configuration settings for the I2C master attribute
*/
typedef struct
{
    uint8_t sampleCnt;      /*!< I2C sample cnt */
    uint8_t stepCnt;        /*!< I2C step cnt */
    ACTION_Type SYNCEn;     /*!< Enable/disable SCL SYNC */
    ACTION_Type ARBEn;      /*!< Enable/disable Arbitration */
} I2C_MasterConfigType;

/*!
* @brief I2C configuration structure for slave attribute
*
* This structure holds the configuration settings for the I2C slave attribute
*/
typedef struct
{
    uint16_t slaveAddr;                 /*!< slave 7/10bit address value */
    uint8_t slaveRangeAddr;             /*!< slave 7bir range address value */
    uint8_t glitchFilterCnt;            /*!< i2c glitch filter cnt */
    ACTION_Type stretchEn;              /*!< Enable/disable slave SCL stretch */
    ACTION_Type txUFInterruptEn;        /*!< Enable/disable slave Tx buff under flow interrupt */
    ACTION_Type rxOFInterruptEn;        /*!< Enable/disable slave Rx buff over flow interrupt */
    ACTION_Type rangeAddrEn;            /*!< Enable/disable slave 7bit range address */
    ACTION_Type monitorEn;              /*!< Enable/disable slave monitor */
    ACTION_Type generalCallEn;          /*!< Enable/disable slave general call */
    ACTION_Type wakeupEn;               /*!< Enable/disable slave address match wakeup */
} I2C_SlaveConfigType;


/*!
* @brief I2C configuration structure
*
* This structure holds the configuration settings for the I2C
*/
typedef struct
{
    I2C_ModeType mode;                  /*!< Select i2c module mode */
    ACTION_Type extAddrEn;             /*!< Enable/disable master/slave 10bit address */
    ACTION_Type ssInterruptEn;          /*!< Enable/disable detect start/stop interrupt */
    ACTION_Type nackInterruptEn;        /*!< Enable/disable get nack interrupt */
    ACTION_Type interruptEn;            /*!< Enable/disable i2c global interrupt */
    ACTION_Type i2cEn;                  /*!< Enable/disable i2c module */
    I2C_MasterConfigType masterConfig;  /*!< i2c master config types */
    I2C_SlaveConfigType slaveConfig;    /*!< i2c slave config types */
    DeviceCallback_Type callBack;       /*!< i2c call back function */
} I2C_ConfigType;

/*!
* @brief I2C master/slave write/read info structure
*
* This structure holds the user configuration info
*/
typedef struct
{
    uint32_t pointer;       /*!< position of send data in user defined buffer */
    uint32_t length;        /*!< length of user defined to write/read */
    uint8_t *buff;          /*!< pointer to user defined buffer */
    I2C_WRType wr;          /*!< i2c transmit type, Master only  */
    ACTION_Type stopEn;     /*!< enable i2c send stop after lastone byte, Master only */
} I2C_TransmitType;

/*!
* @brief I2C instance structure
*
* This structure holds the i2c clock and reset configuration info
*/
typedef struct
{
    I2C_Type *I2Cx;                 /*!< I2C instance: I2C0, I2C1 */
    IRQn_Type I2Cx_IRQn;            /*!< I2C interrupt vector: I2C0_IRQn, I2C1_IRQn */
    CKGEN_ClockType CKGEN_I2Cx;     /*!< I2C module clock: CKGEN_I2C0, CKGEN_I2C1 */
    CKGEN_SoftResetType SRST_I2Cx;  /*!< I2C module reset: SRST_I2C0, SRST_I2C1 */
} I2C_INFOType;

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*!
* @brief Initialize I2C module
*
* @param[in] I2Cx: i2c module
*               - I2C0
* @param[in] config: I2C configuration pointer
* @return none
*/
void I2C_Init(I2C_Type *I2Cx, const I2C_ConfigType *config);

/*!
* @brief I2C De-initialize
*
* @param[in] I2Cx: i2c module
*               - I2C0
* @param[in] config: I2C configuration pointer
* @return none
*/
void I2C_DeInit(I2C_Type *I2Cx);

/*!
* @brief set I2C Callback function
*
* @param[in] I2Cx: i2c module
*               - I2C0
* @param[in] callback: call back function
* @return none
*/
void I2C_SetCallback(I2C_Type *I2Cx, DeviceCallback_Type callback);

/*!
* @brief I2C send start
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c hardware status
*/
uint32_t I2C_Start(I2C_Type *I2Cx);

/*!
* @brief I2C send re-start
*        make sure to disable start/stop interrupt when use the interface
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c hardware status
*/
uint32_t I2C_Restart(I2C_Type *I2Cx);

/*!
* @brief I2C send stop
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c hardware status
*/
uint32_t I2C_Stop(I2C_Type *I2Cx);

/*!
* @brief wait one byte transmit finished
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c hardware status
*/
uint32_t I2C_WaitOneByteFinished(I2C_Type *I2Cx);

/*!
* @brief I2C write one byte with polling BND flag
*        make sure to disable interrupt when use the interface
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] data: data to write
* @return i2c hardware status
*/
uint32_t I2C_TransmitOneByte(I2C_Type *I2Cx, uint8_t data);

/*!
* @brief I2C read one byte and send next clock
*        make sure to disable interrupt when use the interface
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] data: data to read
* @param[in] nack: the next byte ack status
* @return i2c hardware status
*/
uint32_t I2C_ReceiveOneByte(I2C_Type *I2Cx, uint8_t *data, I2C_AckType nack);

/*!
* @brief I2C read one byte without send next clock
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] data: data to read
* @return none
*/
void I2C_ReceiveLastOneByte(I2C_Type *I2Cx, uint8_t *data);

/*!
* @brief I2C get internal hardware ready status
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c hardware status
*/
uint32_t I2C_WaitForReady(I2C_Type *I2Cx);

/*!
* @brief I2C burst write with 7bit/10bit addressing
*        make sure to disable interrupt when use the interface
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] slaveAddr: slave 7bit/10bit address
* @param[in] buff: the data buffer
* @param[in] dataLength: the length to write
* @param[in] stopEn: enable/diable i2c send stop after lastone byte for a possible re-start
* @return i2c hardware status
*/
uint32_t I2C_MasterTransmitPoll(I2C_Type *I2Cx, uint16_t slaveAddr, uint8_t *buff, uint32_t dataLength, ACTION_Type stopEn);

/*!
* @brief I2C burst read with 7bit/10bit addressing
*        make sure to disable interrupt when use the interface
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] slaveAddr: slave 7bit/10bit address
* @param[in] buff: the data buffer
* @param[in] dataLength: the length to read
* @return i2c hardware status
*/
uint32_t I2C_MasterReceivePoll(I2C_Type *I2Cx, uint16_t slaveAddr, uint8_t *buff, uint32_t dataLength);

#ifdef I2C_USE_INTERRUPT_TRANSMIT
/*!
* @brief I2C burst write with 7/10bit addressing by interrupt handler
*         related to variable: g_i2cTransmitInfo
*         related to function: I2C_MasterSlaveIntHandler
*         I2C interrupt must be enable
*         Stop will directly generate if master get an nack
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] slaveAddr: slave 7/10bit address
* @param[in] buff: the data buffer
* @param[in] dataLength: the length to write
* @param[in] stopEn: enable/diable i2c send stop after lastone byte for a possible re-start
* @return i2c hardware status
*/
uint32_t I2C_MasterTransmitInt(I2C_Type *I2Cx, uint16_t slaveAddr, uint8_t *buff, uint32_t dataLength, ACTION_Type stopEn);

/*!
* @brief I2C burst read with 7/10bit addressing by interrupt handler
*         related to variable: g_i2cTransmitInfo
*         related to function: I2C_MasterSlaveIntHandler
*         I2C interrupt must be enable
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] slaveAddr: slave 7/10bit address
* @param[in] buff: the data buffer
* @param[in] dataLength: the length to read
* @return i2c hardware status
*/
uint32_t I2C_MasterReceiveInt(I2C_Type *I2Cx, uint16_t slaveAddr, uint8_t *buff, uint32_t dataLength);

/*!
* @brief I2C slave burst write/read by interrupt handler
*         related to variable: g_i2cTransmitInfo
*         related to function: I2C_MasterSlaveIntHandler
*         I2C interrupt must be enable
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @param[in] buff: the data buffer
* @param[in] dataLength: the length to write/read
* @return none
*/
void I2C_SlaveTransmitReceiveInt(I2C_Type *I2Cx, uint8_t *buff, uint32_t dataLength);

/*!
* @brief get transmit status when use
*        I2C_MasterTransmitInt, I2C_MasterReceiveInt, I2C_SlaveTransmitReceiveInt
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return i2c application status
*/
uint32_t I2C_GetTransmitReceiveStatus(I2C_Type *I2Cx);

/*!
* @brief reset transmit status to I2C_TRANSMIT_STATUS_ERROR_NULL before using
*        I2C_MasterTransmitInt, I2C_MasterReceiveInt, I2C_SlaveTransmitReceiveInt
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return none
*/
void I2C_ResetTransmitReceiveStatus(I2C_Type *I2Cx);

/*!
* @brief get transmitted length when use I2C_MasterTransmitInt, I2C_MasterReceiveInt, I2C_SlaveTransmitReceiveInt
*
* @param[in] I2Cx: I2C module
*               - I2C0
* @return transmitted length
*/
uint32_t I2C_GetTransmittedReceivedLength(I2C_Type *I2Cx);

#endif /* I2C_USE_INTERRUPT_TRANSMIT */

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _AC780X_I2C_H */

/* =============================================  EOF  ============================================== */
