/**
  ******************************************************************************
  * @file    i2c_drv.h
  * @author  Product application department
  * @version V1.0
  * @date    2020.02.13
  * @brief   Header file of I2C DRV module.
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_DRV_H
#define __I2C_DRV_H

#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "drv_reg.h"
#include "drv_gpio_def.h"


#ifdef FILE_OUT
/**@defgroup DRV 3 HAL driver
  *
  *@{
  */

/** @defgroup DRV_I2C I2C
  *
  *@{
  */
#endif
/*** 宏定义 *******************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_I2C_Exported_Macros Exported Macros
  *
  * @{
  */
#endif

/**
  * @brief  I2C 常用宏常量
  *
  */
#define I2C_SPEED_NORMAL                           (1)                       /**< I2C模块 速度常速              */
#define I2C_SPEED_HIGH                             (2)                       /**< I2C模块 速度高速              */
#define I2C_DIR_READ                               (1)                       /**< I2C模块 方向读                */
#define I2C_DIR_WRITE                              (2)                       /**< I2C模块 方向写                */

#define I2C_MASTER_CODE                 ((uint8_t)(0X0A))                    /**< I2C高速模式时主机码 */
#define I2C_SUBADD                      ((uint8_t)(0x80))                    /**< I2C 通信含有子地址  */

#define I2C_SUB_ADD_BYTES_1             ((uint8_t)(0x01))                    /**< I2C 子地址长度为1bytes*/
#define I2C_SUB_ADD_BYTES_2             ((uint8_t)(0x02))                    /**< I2C 子地址长度为2bytes*/
#define I2C_SUB_ADD_BYTES_3             ((uint8_t)(0x03))                    /**< I2C 子地址长度为3bytes*/
#define I2C_SUB_ADD_BYTES_4             ((uint8_t)(0x04))                    /**< I2C 子地址长度为4bytes*/

#define I2C_ERROR_OK                               (0X00)                                          /**< 错误:无                       */
#define I2C_ERROR_CLOCK_FACTOR                     (0X01)                                          /**< 可能返回的错误值:分频因子     */
#define I2C_ERROR_CLOCK_PRESCALER                  (0X02)
#define I2C_ERROR_ABRL                             (0X03)                                          /**< 错误:无                       */
#define I2C_ERROR_AACK                             (0X04)                                          /**< 错误:无                       */
/**< 可能返回的错误值:分频系数     */

#define _i2c_slave_set_addr(i2c,addr)                  _reg_write(i2c->SAR,addr)                              /**< 设置本机作为从设备时的地址    */
#define _i2c_en(i2c)                                   _bit_set(i2c->CCR,I2C_EN)                              /**< I2C模块使能                   */
#define _i2c_dis(i2c)                                  _bit_clr(i2c->CCR,I2C_EN)                              /**< I2C模块禁止                   */
#define _i2c_en_it(i2c)                                _bit_set(i2c->CCR,I2C_EN_IT)                           /**< 中断使能                      */
#define _i2c_dis_it(i2c)                               _bit_clr(i2c->CCR,I2C_EN_IT)                           /**< 中断禁能                      */

#define _i2c_bus_start           				       _bit_set(I2C->CR,I2C_MASTER)                           /**< 生成起始条件                  */
#define _i2c_bus_stop 				                   _bit_clr(I2C->CR,I2C_MASTER)                           /**< 产生结束条件                  */
#define _i2c_bus_ack 							       _bit_set(I2C->CR,I2C_EN_ACK)                           /**< 应答                          */
#define _i2c_bus_nack                                  _bit_clr(I2C->CR,I2C_EN_ACK)                           /**< 非应答                        */

#define _i2c_generate_start(i2c) 				       _bit_set(i2c->CCR,I2C_MASTER)                          /**< 生成起始条件                  */
#define _i2c_generate_stop(i2c) 				       _bit_clr(i2c->CCR,I2C_MASTER)                          /**< 产生结束条件                  */
#define _i2c_ack(i2c) 							       _bit_set(i2c->CCR,I2C_EN_ACK)                          /**< 应答                          */
#define _i2c_nack(i2c)                                 _bit_clr(i2c->CCR,I2C_EN_ACK)                          /**< 非应答                        */
#define _i2c_repeat_start(i2c)                         _bit_set(i2c->CCR,I2C_EN_REPEAT_START)                 /**< 产生重复起始条件              */
#define _i2c_reset_repeat_start(i2c)                   _bit_clr(i2c->CCR,I2C_EN_REPEAT_START)                 /**< 复位重复起始条件              */
#define _i2c_en_add_match_it(i2c)                      _bit_set(i2c->CCR,I2C_EN_ADDRESS_MATCH_IT)             /**< 地址匹配中断使能              */
#define _i2c_dis_add_match_it(i2c)                     _bit_clr(i2c->CCR,I2C_EN_ADDRESS_MATCH_IT)             /**< 地址匹配中断禁能              */
#define _i2c_en_highspeed(i2c)                         _bit_set(i2c->CCR,I2C_EN_HIGH_SPEED_MODE)              /**< 高速模式使能                  */
#define _i2c_dis_highspeed(i2c)                        _bit_clr(i2c->CCR,I2C_EN_HIGH_SPEED_MODE)              /**< 高速模式使能                  */
#define _i2c_en_slave_highspeed_it(i2c)                _bit_set(i2c->CCR,I2C_EN_SLAVE_HIGH_SPEED_MODE_IT)     /**< 从高速模式中断使能            */
#define _i2c_dis_slave_highspeed_it(i2c)               _bit_get(i2c->CCR,I2C_EN_SLAVE_HIGH_SPEED_MODE_IT)     /**< 从高速模式中断禁能            */

#define _i2c_get_flag_tf(i2c)                          _bit_get(i2c->SR,I2C_FLAG_TF)                          /**< 攻取TF标志                    */
#define _i2c_get_flag_rc(i2c)                          _bit_get(i2c->SR,I2C_FLAG_RC)                          /**< 攻取RC标志                    */
#define _i2c_get_flag_aaslv(i2c)                       _bit_get(i2c->SR,I2C_FLAG_AASLV)                       /**< 攻取AASLV标志                 */
#define _i2c_get_flag_busy(i2c)                        _bit_get(i2c->SR,I2C_FLAG_BUSY)                        /**< 攻取BUSY标志                  */
#define _i2c_get_flag_arbl(i2c)                        _bit_get(i2c->SR,I2C_FLAG_ARBL)                        /**< 攻取ARBL标志                  */
#define _i2c_get_flag_rxtx(i2c)                        _bit_get(i2c->SR,I2C_FLAG_RXTX)                        /**< 攻取RXTX标志                  */
#define _i2c_get_flag_dack(i2c)                        _bit_get(i2c->SR,I2C_FLAG_DACK)                        /**< 攻取DACK标志                  */
#define _i2c_get_flag_aack(i2c)                        _bit_get(i2c->SR,I2C_FLAG_AACK)                        /**< 攻取AACK标志                  */
#define _i2c_get_flag_slave_high_speed(i2c)            _bit_get(i2c->SHIR,I2C_FLAG_SLAVE_HIGH_SPEED)          /**< 攻取SLAVE HIGH SPEED MODE标志 */
#define _i2c_clr_flag_slave_high_speed(i2c)            _bit_set(i2c->SHIR,I2C_FLAG_SLAVE_HIGH_SPEED)          /**< 攻取SLAVE HIGH SPEED MODE标志 */
#define _i2c_get_status(i2c)                           _reg_read(i2c->SR)                                     /**< 获取整个状态值                */

#define _i2c_en_clock_test_mode(i2c)                   _bit_set(i2c->PR,I2C_CLOCK_MODE_TEST )                 /**< I2C 置位分频寄存器测试位      */
#define _i2c_dis_clock_test_mode(i2c)                  _bit_clr(i2c->PR,I2C_CLOCK_MODE_TEST)                  /**< I2C 复位分频寄存器测试位      */
#define _i2c_en_clock_normal_mode(i2c)                 _bit_clr(i2c->PR,I2C_CLOCK_MODE_TEST)                  /**< I2C 置位分频寄存器测试位      */
#define _i2c_dis_clock_normal_mode(i2c)                _bit_clr(i2c->PR,I2C_CLOCK_MODE_TEST)                  /**< I2C 复位分频寄存器测试位      */

#define _i2c_pin_pullup_en(i2c,pin)                    _bit_set(i2c->PCR,1<<(pin + I2C_PU_SHIFT_MASK))        /**<                */
#define _i2c_pin_pullup_dis(i2c,pin)                   _bit_clr(i2c->PCR,1<<(pin + I2C_PU_SHIFT_MASK))        /**<                */
#define _i2c_pin_pulldown_en(i2c,pin)                  _bit_set(i2c->PCR,1<<(pin + I2C_PD_SHIFT_MASK))        /**<                */
#define _i2c_pin_pulldown_dis(i2c,pin)                 _bit_clr(i2c->PCR,1<<(pin + I2C_PD_SHIFT_MASK))        /**<                */
#define _i2c_pin_output_cmos(i2c,pin)                  _bit_set(i2c->PCR,1<<(pin + I2C_WOM_SHIFT_MASK))       /**<                */
#define _i2c_pin_output_opendrain(i2c,pin)             _bit_clr(i2c->PCR,1<<(pin + I2C_WOM_SHIFT_MASK))       /**<                */

#define _i2c_set_sda_bit(i2c)                          _bit_set(i2c->PDR,1<<I2C_PIN_SDA)                      /**< 置位SDA管脚电平               */
#define _i2c_reset_sda_bit(i2c)                        _bit_clr(i2c->PDR,(1<<I2C_PIN_SDA))                    /**< 复位SDA管脚电平               */
#define _i2c_set_scl_bit(i2c)                          _bit_set(i2c->PDR,1<<I2C_PIN_SCL)                      /**< 置位SCL管脚电平               */
#define _i2c_reset_scl_bit(i2c)                        _bit_clr(i2c->PDR,(1<<I2C_PIN_SCL))                    /**< 复位SCL管脚电平               */
#define _i2c_get_sda_bit(i2c)                          _bit_get(i2c->PDR,(1<<I2C_PIN_SDA))                    /**< 获取SDA管脚电平               */
#define _i2c_get_scl_bit(i2c)                          _bit_get(i2c->PDR,(1<<I2C_PIN_SCL))                    /**< 获取SCL管脚电平               */
#define _i2c_pin_gpio(i2c,pin)                         _bit_set(i2c->PCR,1<<(pin+I2C_PA_SHIFT_MASK))          /**<                */
#define _i2c_pin_primary_fun(i2c,pin)                  _bit_clr(i2c->PCR,1<<(pin+I2C_PA_SHIFT_MASK))          /**<                */

#define _i2c_scl_configure_as_gpio(i2c)                _bit_set(i2c->PCR,I2C_PIN_SCL_GPIO)                    /**<                */
#define _i2c_scl_configure_as_primary(i2c)             _bit_clr(i2c->PCR,I2C_PIN_SCL_GPIO)                    /**<                */
#define _i2c_sda_configure_as_gpio(i2c)                _bit_set(i2c->PCR,I2C_PIN_SDA_GPIO)                    /**<                */
#define _i2c_sda_configure_as_primary(i2c)             _bit_clr(i2c->PCR,I2C_PIN_SDA_GPIO)                    /**<                */

#define _i2c_scl_cmos_mode(i2c)                        _bit_clr(i2c->PCR,I2C_PIN_SCL_CMOS_MODE)               /**< 设置SCL管脚CMOS输出方式       */
#define _i2c_scl_open_drain_mode(i2c)                  _bit_set(i2c->PCR,I2C_PIN_SCL_CMOS_MODE)               /**< 设置SCL管脚OPENDRAIN`输出方式 */
#define _i2c_sda_cmos_mode(i2c)                        _bit_clr(i2c->PCR,I2C_PIN_SDA_CMOS_MODE)               /**< 设置SDA管脚CMOS输出方式       */
#define _i2c_sda_open_drain_mode(i2c)                  _bit_set(i2c->PCR,I2C_PIN_SDA_CMOS_MODE)               /**< 设置SDA管脚OPENDRAIN输出方式  */

#define _i2c_scl_dis_pullup(i2c)                       _bit_clr(i2c->PCR,I2C_PIN_SCL_EN_PULLUP)               /**< 禁止SCL管脚上拉               */
#define _i2c_scl_en_pullup(i2c)                        _bit_set(i2c->PCR,I2C_PIN_SCL_DIS_PULLUP)              /**< 使能SCL管脚上拉               */
#define _i2c_sda_dis_pullup(i2c)                       _bit_clr(i2c->PCR,I2C_PIN_SDA_EN_PULLUP)               /**< 禁止SDA管脚上拉               */
#define _i2c_sda_en_pullup(i2c)                        _bit_set(i2c->PCR,I2C_PIN_SDA_DIS_PULLUP)              /**< 使能SDA管脚上拉               */

#define _i2c_sda_dir_output(i2c)                       _bit_set(i2c->DDR,0X02)                                /**< SCL方向输出                   */
#define _i2c_sda_dir_input(i2c)                        _bit_clr(i2c->DDR,0X02)                                /**< SCL方向输入                   */
#define _i2c_scl_dir_output(i2c)                       _bit_set(i2c->DDR,0X01)                                /**< SDA方向输出                   */
#define _i2c_scl_dir_input(i2c)                        _bit_clr(i2c->DDR,0X01)                                /**< SDA方向入                   */

#define _i2c_pin_dir_output(i2c,pin)                   _bit_set(i2c->DDR,(1<<pin))                            /**< 方向输出                   */
#define _i2c_pin_dir_input(i2c,pin)                    _bit_clr(i2c->DDR,(1<<pin))                            /**< 方向输入                   */
#define _i2c_set_pin_bit(i2c,pin)                      _bit_set(i2c->PDR,(1<<pin))                            /**< 置位管脚电平               */
#define _i2c_reset_pin_bit(i2c,pin)                    _bit_clr(i2c->PDR,(1<<pin))                            /**< 复位管脚电平               */
#define _i2c_get_pin_bit(i2c,pin)                      _bit_get(i2c->PDR,(1<<pin))

/**
  * @}
  */

/*** 结构体、枚举变量定义 *****************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_I2C_Exported_Types Exported Types
  *
  * @{
  */
#endif

/**
  * @brief i2c通信状态枚举
  */
typedef enum
{
  DRV_I2C_STATE_RESET             = 0x00,  /**< I2C not yet initialized or disabled         */
  DRV_I2C_STATE_READY             = 0x01,  /**< I2C initialized and ready for use           */
  DRV_I2C_STATE_BUSY              = 0x02,  /**< I2C internal process is ongoing             */
  DRV_I2C_STATE_BUSY_TX           = 0x12,  /**< Data Transmission process is ongoing        */
  DRV_I2C_STATE_BUSY_RX           = 0x22,  /**< Data Reception process is ongoing           */
  DRV_I2C_STATE_TIMEOUT           = 0x03,  /**< I2C timeout state                           */
  DRV_I2C_STATE_ERROR             = 0x04,  /**< I2C error state                             */
}DRV_IicStateTypeDef;

/**
  * @brief i2c主从模式定义
  */
typedef enum
{
	I2C_MODE_MASTER,
	I2C_MODE_SLAVE,
}I2C_ModeTypeDef;
	
/**
  * @brief i2cbit位定义
  */
typedef enum
{
I2C_SLAVE_ADD_7BITS,
I2C_SLAVE_ADD_10BITS,
}I2C_SlaveAddBitsTypeDef;

/**
  * @brief i2c状态定义
  */
typedef enum
{
  DRV_I2C_OK       = 0x00,
  DRV_I2C_ERROR    = 0x01,
  DRV_I2C_BUSY     = 0x02,
  DRV_I2C_TIMEOUT  = 0x03,
}DRV_I2C_StatusTypeDef;

/**
  * @brief i2c标志索引定义
  */
typedef enum
{
	I2C_FLAG_INDEX_TF,
	I2C_FLAG_INDEX_RC,
	I2C_FLAG_INDEX_ASLV,
	I2C_FLAG_INDEX_BUSY,
	I2C_FLAG_INDEX_ARBL,
	I2C_FLAG_INDEX_RXTX,
	I2C_FLAG_INDEX_DACK,
	I2C_FLAG_INDEX_AACK,
}I2C_FlagIndexTypeDef;
	
/**
  * @brief i2c中断索引定义
  */
typedef enum
{
	I2C_IT_INDEX_IEN=0X02,
	I2C_IT_INDEX_AMIE=0X20,
	I2C_IT_INDEX_SLV_HSIE=0X80,
}I2C_ItIndexTypeDef;
	
/**
  * @brief i2c初始定义
  */
typedef struct
{
    uint8_t Mode;          /**<I2C工作于主模式还是从模式
                            *- I2C_MODE_MASTER
                            *- I2C_MODE_SLAVE
                            */
    uint8_t Prescaler;     /**<I2C时钟分频值*/
    uint8_t ClockMode;     /**<I2C时钟模式
                             *- I2C_CLOCK_TEST_MODE
                             *- I2C_CLOCK_NORMAL_MODE
                             */
    uint8_t HighSpeed;     /**< I2C 高速模式使能或禁止
                             *- ENABLE
                             *- DISABLE
                             */   
    uint16_t Add;          /**< 作为从设备时设备地址 */
    uint8_t  AddBits;      /**< 地址长度*/							 
}I2C_InitTypeDef;

/**
  * @}
  */

/*** 全局变量声明 **************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_I2C_Exported_Variables Exported Variables
  *
  * @{
  */
#endif


/**
  * @}
  */

/*** 函数声明 ******************************************************************/
#ifdef FILE_OUT
/** @defgroup DRV_I2C_Exported_Functions Exported Functions
  * @{
  */
#endif

DRV_I2C_StatusTypeDef DRV_I2C_DeInit(I2C_TypeDef *pi2c);
DRV_I2C_StatusTypeDef DRV_I2C_Init(I2C_TypeDef *pi2c, I2C_InitTypeDef *pinit);
void DRV_I2C_Cmd(I2C_TypeDef *pi2c, FunctionalStateTypeDef NewState);
void DRV_I2C_ItCmd(I2C_TypeDef *pi2c, 
	               I2C_ItIndexTypeDef index, 
	               FunctionalStateTypeDef NewState);
DRV_I2C_StatusTypeDef DRV_I2C_GetFlag(I2C_TypeDef *pi2c,
                                      I2C_FlagIndexTypeDef index,
                                      FlagStatusTypeDef *pFlag);
DRV_I2C_StatusTypeDef  DRV_I2C_WaitonFlagTimeout(I2C_TypeDef *pi2c,
                                                 I2C_FlagIndexTypeDef index,
                                                 FlagStatusTypeDef status,
                                                 uint32_t timeout);
DRV_I2C_StatusTypeDef  DRV_I2C_WaitonSlvHsFlagTimeout(I2C_TypeDef *pi2c,
                                                      FlagStatusTypeDef status,
                                                      uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MasterWriteRequest(I2C_TypeDef *pi2c, 
	                                             uint8_t SlaveAdd, 
	                                             uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MasterReadRequest(I2C_TypeDef *pi2c, 
	                                            uint8_t SlaveAdd, 
	                                            uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MasterGenerateStop(I2C_TypeDef *pi2c, 
	                                             FunctionalStateTypeDef NewState, 
	                                             uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MasterRestartReadRequest(I2C_TypeDef *pi2c, 
	                                                   uint8_t SlaveAdd, 
	                                                   uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MasterHighspeedWriteRequest(I2C_TypeDef *pi2c,
                                                          uint8_t SLaveAdd,
                                                          uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_TransmitByte(I2C_TypeDef *pi2c, 
	                                       uint8_t tosend, 
	                                       uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_ReceiveByte(I2C_TypeDef *pi2c, 
	                                      uint8_t *Rx, 
	                                      uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_Transmit(I2C_TypeDef *pi2c,
                                       uint8_t SlaveAdd,
                                       FunctionalStateTypeDef Highspeed,
                                       uint8_t *pBuf,
                                       uint32_t Size,
                                       uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_Receive(I2C_TypeDef *pi2c,
                                      uint8_t SlaveAdd,
                                      FunctionalStateTypeDef Highspeed,
                                      uint8_t *pBuf,
                                      uint32_t Size,
                                      uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_TransmitIT(I2C_TypeDef *pi2c,
                                         uint8_t SlaveAdd,
                                         FunctionalStateTypeDef Highspeed,
                                         uint8_t *pBuf,
                                         uint32_t Size);
DRV_I2C_StatusTypeDef DRV_I2C_ReceiveIT(I2C_TypeDef *pi2c,
                                        uint8_t SlaveAdd,
                                        FunctionalStateTypeDef Highspeed,
                                        uint8_t *pBuf,
                                        uint32_t Size);
DRV_I2C_StatusTypeDef DRV_I2C_MemWrite(I2C_TypeDef *pi2c,
                                       uint8_t SlaveAdd,
                                       uint32_t MemAdd,
                                       uint8_t  MemAddBytes,
                                       FunctionalStateTypeDef Highspeed,
                                       uint8_t *pBuf,
                                       uint32_t Size,
                                       uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_MemRead(I2C_TypeDef *pi2c,
                                      uint8_t SlaveAdd,
                                      uint32_t MemAdd,
                                      uint8_t  MemAddBytes,
                                      FunctionalStateTypeDef Highspeed,
                                      uint8_t *pBuf,
                                      uint32_t Size,
                                      uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_SlaveTransmitReceive(I2C_TypeDef *pi2c,
                                                   uint8_t *pBuf,
                                                   uint32_t Size,
                                                   uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_SlaveTransmit(I2C_TypeDef *pi2c,
                                            uint8_t *pBuf,
                                            uint32_t Size,
                                            uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_SlaveReceive(I2C_TypeDef *pi2c,
                                           uint8_t *pBuf,
                                           uint32_t Size,
                                           uint32_t timeout);
DRV_I2C_StatusTypeDef DRV_I2C_GetItSource(I2C_TypeDef *pi2c,
                                          uint8_t *pItSource);	
DRV_I2C_StatusTypeDef DRV_I2C_GetItFlags(I2C_TypeDef *pi2c, 
	                                     uint8_t *pBasicFlags, 
	                                     uint8_t *pSlvHighspeedFlags);
void DRV_I2C_GetDR(I2C_TypeDef *pi2c, uint8_t *pData);
void DRV_I2C_SetDR(I2C_TypeDef *pi2c, uint8_t Data);

DRV_I2C_StatusTypeDef DRV_I2C_GpioInit(I2C_TypeDef *pi2c, GPIO_InitTypeDef *Init);
DRV_I2C_StatusTypeDef DRV_I2C_GpioDeInit(I2C_TypeDef *pi2c, uint8_t pin);
void DRV_I2C_WritePin(I2C_TypeDef *pi2c, 
	                  uint8_t pin, 
	                  GPIO_PinStateTypeDef state);
BitActionTypeDef DRV_I2C_ReadPin(I2C_TypeDef *pi2c, uint8_t pin);
void DRV_I2C_TogglePin(I2C_TypeDef *pi2c, uint8_t pin);

/**
  * @}
  */

/**
  *@}
  */

/**
  *@}
  */

#ifdef __cplusplus
}

#endif

#endif /* __I2C_DRV_H */

