/**
  **********************************************************************************
  * @file    i2c_hal.c
  * @author  Product application department
  * @version V1.0
  * @date    2020.02.13
  * @brief   I2C模块HAL层驱动.
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
*/

#include "i2c_hal.h"


/*** 全局变量定义 ***************************************************************/
/** @
  * @{volatile
  */
/** @ 
  * @}
  */
/** @ 
  * @{static
  */
/** @ 
  * @}
  */
/*** 常量定义 *******************************************************************/
/** @
  * @{const
  */
/** @ 
  * @}
  */

/*** 函数定义 *******************************************************************/

/**
  *@brief 将DRV层状态转化为HAL层的状态.
  *-
  *@param[in] DrvStatus驱动层状态，参见@ref DRV_I2C_StatusTypeDef
  *@retval @ref HAL_StatusTypeDef
  */
static HAL_StatusTypeDef DrvStatusToHalStatus(DRV_I2C_StatusTypeDef DrvStatus)
{
    switch(DrvStatus)
    {
        case DRV_I2C_OK:
        {
            return(HAL_OK);
        }

        case DRV_I2C_ERROR:
        {
            return(HAL_ERROR);
        }

        case DRV_I2C_BUSY:
        {
            return(HAL_BUSY);
        }

        case DRV_I2C_TIMEOUT:
        {
            return(HAL_TIMEOUT);
        }
    }
}
/**
  *@brief 初始化I2C_HandleTypeDef结构体指定的I2C模块的管脚、时钟、中断等配置..
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in]
  *@retval @ref HAL_StatusTypeDef
  */
__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{

}
/**
  *@brief 恢复I2C_HandleTypeDef结构体指定的I2C模块的管脚、时钟、中断等配置..
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in]
  *@retval @ref HAL_StatusTypeDef
  */
__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) 
{

}
/**
  *@brief 根据I2C_InitTypeDef指定的参数初始化I2C模块,并初始化相关handle.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
{
    if(hi2c->State == HAL_I2C_STATE_RESET)
    {
        HAL_I2C_MspInit(hi2c);
    }

    hi2c->State = HAL_I2C_STATE_BUSY;

    /*初始化硬件层相关*/
    DRV_I2C_Init(hi2c->Instance, &hi2c->Init);

    hi2c->XferCnt = 0;
    hi2c->XferSize = 0;
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
    /*状态更改为READY*/
    hi2c->State = HAL_I2C_STATE_READY;

    return(HAL_OK);
}
/**
  *@brief 恢复I2C模块到初始状态.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
{
    hi2c->State = HAL_I2C_STATE_BUSY;

    /**/
    DRV_I2C_DeInit(hi2c->Instance);

    hi2c->XferCnt = 0;
    hi2c->XferSize = 0;
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
    hi2c->State = HAL_I2C_STATE_RESET;
    hi2c->XferISR = 0;

    return(HAL_OK);
}
/**
  *@brief I2C作为主机模式时中断服务.
  *
  *@param[in] hi2c                指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] BasicFlags          除高速模式之外状态;
  *@param[in] SlaveHighspeedFlags 高速模式状态;
  *@param[in] 中断源;
  *@retval 无
  */
void HAL_I2C_MasterIRQHandler(I2C_HandleTypeDef *hi2c,
                              uint8_t BasicFlags,
                              uint8_t SlaveHighspeedFlags,
                              uint8_t ItSource)
{
	uint32_t loop = 0;
    uint8_t I2CStatus;
    uint8_t I2CHighspeedStatus;
    volatile uint8_t tmp = 0;
    uint8_t TmpItSourceFlag;

    /**************************************************************/
    /*获取中断状态*/
    I2CStatus = BasicFlags;
    I2CHighspeedStatus = SlaveHighspeedFlags;
    TmpItSourceFlag = ItSource & I2C_IT_INDEX_IEN;

    if((I2CStatus & (I2C_FLAG_RC | I2C_FLAG_TF)))
    {
        {
            if((I2CStatus & I2C_FLAG_RXTX) != I2C_FLAG_RXTX)
            {
                /**************************************************************/
                /*处于接收模式:接收数据或者发送完读取请求之后的中断*/
                if(hi2c->State == HAL_I2C_STATE_BUSY_DEVADD_READ)
                {
                    /*转入接收数据阶段*/
					if(hi2c->XferSize == 1)
					{
                	    _i2c_nack(hi2c->Instance);
					}
					else
					{	
						_i2c_ack(hi2c->Instance);
					}
                    hi2c->State =HAL_I2C_STATE_BUSY_RX;
					hi2c->XferCnt = 0;
                }
                else
                {
                    /*接收到的是数据*/					
					DRV_I2C_GetDR(hi2c->Instance, (hi2c->pXferBuf + hi2c->XferCnt));
					hi2c->XferCnt++;
										
					if(hi2c->XferCnt >= hi2c->XferSize)
                    {
                        hi2c->XferCnt = hi2c->XferSize;
                        
						/*产生停止条件:因无停止条件中断，需要查询BUSY*/
						#if 0
							_i2c_generate_stop(hi2c->Instance);
						#else							
							DRV_I2C_MasterGenerateStop(hi2c->Instance,DISABLE,0);
						#endif

						_i2c_dis_it(hi2c->Instance);
						hi2c->State = HAL_I2C_STATE_READY;
                    }
					else
					{
						if(hi2c->XferSize > 1)
						{
							if(hi2c->XferCnt == (hi2c->XferSize -1))
		                    {
			                    /*最后一个字节应答*/
			                    _i2c_nack(hi2c->Instance);
						    }
							else
							{
								/*应答*/
								_i2c_ack(hi2c->Instance);
							}
		                    
						}
					}
                }
            }/*接收模式*/
            /**************************************************************/
            /**************************************************************/
            else
            {
                //if(hi2c->State == HAL_I2C_STATE_BUSY_MEM_TX)
                {
                    if(hi2c->XferCnt == hi2c->XferSize)
                    {
                        hi2c->State = HAL_I2C_STATE_READY;
                        hi2c->XferCnt = hi2c->XferSize;                        
						/*发送停止条件*/
						/*产生停止条件:因无停止条件中断，需要查询BUSY*/
						#if 0
							_i2c_generate_stop(hi2c->Instance);
						#else
						    DRV_I2C_MasterGenerateStop(hi2c->Instance,DISABLE,0);
						#endif
						
						_i2c_dis_it(hi2c->Instance);
                    }
					else
					{
	                    /*数据阶段*/
						DRV_I2C_SetDR(hi2c->Instance, *(hi2c->pXferBuf + hi2c->XferCnt));

	                    hi2c->XferCnt++;
					}
                }
            }/*发送模式*/

            /**************************************************************/
        }
    }
}
/**
  *@brief 查循方式通过指定的I2C端口发送数据.
  *
  *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址;
  *@param[in] pData      待发送数据指针;
  *@param[in] Size       待发送数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_MasterTransmit(I2C_HandleTypeDef *hi2c,
                                         uint16_t DevAddress,
                                         uint8_t *pData,
                                         uint16_t Size,
                                         uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;
        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_Transmit(hi2c->Instance,
                                     DevAddress,
                                     hi2c->Init.HighSpeed,
                                     hi2c->pXferBuf,
                                     hi2c->XferSize,
                                     Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            hi2c->State = HAL_I2C_STATE_READY;
            HalStatus = DrvStatusToHalStatus(DrvStatus);
            return(HalStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
  *@brief 查循方式通过指定的I2C端口发送数据.
  *
  *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址;
  *@param[in] pData      待发送数据指针;
  *@param[in] Size       待发送数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_MasterRecceive(I2C_HandleTypeDef *hi2c,
                                         uint16_t DevAddress,
                                         uint8_t *pData,
                                         uint16_t Size,
                                         uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_RX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;
        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_Receive(hi2c->Instance,
                                    DevAddress,
                                    hi2c->Init.HighSpeed,
                                    hi2c->pXferBuf,
                                    hi2c->XferSize,
                                    Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            hi2c->State = HAL_I2C_STATE_READY;
            HalStatus = DrvStatusToHalStatus(DrvStatus);
            return(HalStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
*@brief 中断方式通过指定的I2C端口发送数据.
*
*@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
*@param[in] DevAddress 从机地址;
*@param[in] pData      待发送数据指针;
*@param[in] Size       待发送数据长度;
*@param[in] Timeou     超时时间;
*@retval @ref HAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_MasterTransmitIT(I2C_HandleTypeDef *hi2c,
                                           uint16_t DevAddress,
                                           uint8_t *pData,
                                           uint16_t Size,
                                           uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        hi2c->MemAdd = 0;
        hi2c->MemAddSize = 0;
        hi2c->XferFlag = 0;
        /*中断处理函数*/
        hi2c->XferISR = HAL_I2C_MasterIRQHandler;

        /*发送起始条件*/
        _i2c_en_it(hi2c->Instance);
	    	_i2c_dis_add_match_it(hi2c->Instance);
        DevAddress &= ~0x01;
        DRV_I2C_SetDR(hi2c->Instance, DevAddress);
        _i2c_generate_start(hi2c->Instance);
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
  *@brief 查循方式通过指定的I2C端口发送数据.
  *
  *@param[in]            hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址;
  *@param[in] pData      待发送数据指针;
  *@param[in] Size       待发送数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_MasterReceiveIT(I2C_HandleTypeDef *hi2c,
                                          uint16_t DevAddress,
                                          uint8_t *pData,
                                          uint16_t Size,
                                          uint32_t timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        hi2c->State = HAL_I2C_STATE_BUSY_DEVADD_READ;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        hi2c->MemAdd = 0;
        hi2c->MemAddSize = 0;
        hi2c->XferFlag = 0;
        /*中断处理函数*/
        hi2c->XferISR = HAL_I2C_MasterIRQHandler;

        #if 1
        /*发送起始条件*/
        DevAddress |= 0x01;
        _i2c_en_it(hi2c->Instance);
	    _i2c_dis_add_match_it(hi2c->Instance);
        DRV_I2C_SetDR(hi2c->Instance, DevAddress);
        _i2c_generate_start(hi2c->Instance);
		#else
		_i2c_dis_it(hi2c->Instance);
	    DevAddress |= 0x01;
        DRV_I2C_MasterReadRequest(hi2c->Instance,DevAddress,0);  
		_i2c_ack(hi2c->Instance);
		_i2c_en_it(hi2c->Instance);
		#endif
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
  *@brief I2C作为主机访问存储器模式时中断服务.
  *
  *@param[in] hi2c                指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] BasicFlags          除高速模式之外状态;
  *@param[in] SlaveHighspeedFlags 高速模式状态;
  *@param[in] ItSource            中断源;
  *@retval 无
  */
void HAL_I2C_MasterMemIRQHandler(I2C_HandleTypeDef *hi2c,
                                 uint8_t BasicFlags,
                                 uint8_t SlaveHighspeedFlags,
                                 uint8_t ItSource)
{
    uint32_t loop = 0;
    uint8_t I2CStatus;
    uint8_t I2CHighspeedStatus;
    volatile uint8_t tmp = 0;
    uint8_t TmpItSourceFlag;

    /**************************************************************/
    /*获取中断状态*/
    I2CStatus = BasicFlags;
    I2CHighspeedStatus = SlaveHighspeedFlags;
    TmpItSourceFlag = ItSource & I2C_IT_INDEX_IEN;

    if((I2CStatus & (I2C_FLAG_RC | I2C_FLAG_TF)))
    {
        {
            if((I2CStatus & I2C_FLAG_RXTX) != I2C_FLAG_RXTX)
            {
                /**************************************************************/
                /*处于接收模式:接收数据或者发送完读取请求之后的中断*/
                if(hi2c->State == HAL_I2C_STATE_BUSY_MEM_DEVADD_RESTART_READ)
                {
                    /*转入接收数据阶段*/
					if(hi2c->XferSize == 1)
					{
                	    _i2c_nack(hi2c->Instance);
					}
					else
					{
						_i2c_ack(hi2c->Instance);
					}
                    hi2c->State =HAL_I2C_STATE_BUSY_RX;
                }
                else
                {
                    /*接收到的是数据*/				
					DRV_I2C_GetDR(hi2c->Instance, (hi2c->pXferBuf + hi2c->XferCnt));
					hi2c->XferCnt++;
										
					if(hi2c->XferCnt >= hi2c->XferSize)
                    {
                        hi2c->XferCnt = hi2c->XferSize;
                   
						/*产生停止条件:因无停止条件中断，需要查询BUSY*/
						#if 0
							_i2c_generate_stop(hi2c->Instance);
						#else		
						DRV_I2C_MasterGenerateStop(hi2c->Instance,DISABLE,0);
						#endif

						_i2c_dis_it(hi2c->Instance);
						
						hi2c->State = HAL_I2C_STATE_READY;
                    }
					else
					{
						if(hi2c->XferSize > 1)
						{
										
							if(hi2c->XferCnt == (hi2c->XferSize -1))
		                    {
			                    /*最后一个字节应答*/		
			                    _i2c_nack(hi2c->Instance);
						    }
							else
							{
								/*应答*/
			                    _i2c_ack(hi2c->Instance);
							}
		                    
						}
					}
                }
            }/*接收模式*/
            /**************************************************************/
            /**************************************************************/
            else
            {
                /*发送模式*/	
                if(hi2c->State == HAL_I2C_STATE_BUSY_MEM_SUBADD)
                {                						
                    /*发送器件子地址*/
                    if(hi2c->XferCnt == 0)
					{
						DRV_I2C_SetDR(hi2c->Instance, (uint8_t)hi2c->MemAdd);					}
                    else if(hi2c->XferCnt == 1)
                    {
						DRV_I2C_SetDR(hi2c->Instance, (uint8_t)(hi2c->MemAdd >> 8));
					}
                    else if(hi2c->XferCnt == 2)
					{
						DRV_I2C_SetDR(hi2c->Instance, (uint8_t)(hi2c->MemAdd >> 16));
					}
                    else if(hi2c->XferCnt == 3)
                    {    
						DRV_I2C_SetDR(hi2c->Instance, (uint8_t)(hi2c->MemAdd >> 24));
					}

                    hi2c->XferCnt++;
					
					if(hi2c->XferCnt == hi2c->MemAddSize)
                    {                        
                        hi2c->XferCnt = 0;

                        /*发送完成之后还要判定下次是何操作:
                          如果是读操作则发送完成子地址之后要发送重复起始请求*/
                        if(hi2c->XferFlag == 1)
                        {
                            /*更改下次中断之后要发送重复启起条件:再次中断后进入RC处理*/
                            hi2c->State = HAL_I2C_STATE_BUSY_MEM_DEVADD_RESTART_READ;
                        }
						else
						{
							hi2c->State = HAL_I2C_STATE_BUSY_MEM_TX;
						}
                    }
                    
                }
                else if(hi2c->State == HAL_I2C_STATE_BUSY_MEM_DEVADD_RESTART_READ)
                {
                	/*发送重复起始条件之后会产生RC中断,之后ACK再等RC中断*/
					_i2c_repeat_start(hi2c->Instance);
					hi2c->SubAdd |= 0x01;
					DRV_I2C_SetDR(hi2c->Instance,hi2c->SubAdd);
					_i2c_reset_repeat_start(hi2c->Instance);
                }
                else if(hi2c->State == HAL_I2C_STATE_BUSY_MEM_TX)
                {
                    if(hi2c->XferCnt == hi2c->XferSize)
                    {
                        hi2c->State = HAL_I2C_STATE_READY;
                        hi2c->XferCnt = hi2c->XferSize;                       
						/*发送停止条件*/
						/*产生停止条件:因无停止条件中断，需要查询BUSY*/
						#if 0
							_i2c_generate_stop(hi2c->Instance);
						#else
							DRV_I2C_MasterGenerateStop(hi2c->Instance,DISABLE,0);
						#endif

						_i2c_dis_it(hi2c->Instance);
                    }
					else
					{
	                    /*数据阶段*/
	                    DRV_I2C_SetDR(hi2c->Instance, *(hi2c->pXferBuf + hi2c->XferCnt));

	                    hi2c->XferCnt++;
					}
                }
            }/*发送模式*/
            /**************************************************************/
        }
    }
}
/**
  *@brief 查循方式通过指定的I2C端口发送数据.
  *
  *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址
  *@param[in] MemAddress 从机子地址;
  *@param[in] MemAddSize 从机子地址长度，单位字节;
  *@param[in] pData      待发送数据指针;
  *@param[in] Size       待发送数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @refHAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_I2C_MemWrite(I2C_HandleTypeDef *hi2c,
                                   uint16_t DevAddress,
                                   uint32_t MemAddress,
                                   uint16_t MemAddSize,
                                   uint8_t *pData,
                                   uint16_t Size,
                                   uint32_t Timeout)

{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {		
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;
        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_MemWrite(hi2c->Instance,
                                     DevAddress,
                                     MemAddress,
                                     MemAddSize,
                                     hi2c->Init.HighSpeed,
                                     hi2c->pXferBuf,
                                     hi2c->XferSize,
                                     Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            hi2c->State = HAL_I2C_STATE_READY;
            HalStatus = DrvStatusToHalStatus(DrvStatus);
            return(HalStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
 *@brief 查循方式通过指定的I2C端口发送数据.
 *
 *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
 *@param[in] DevAddress 从机地址;
 *@param[in] MemAddress 从机子地址;
 *@param[in] MemAddSize 从机子地址长度，单位字节;
 *@param[in] pData      待发送数据指针;
 *@param[in] Size       待发送数据长度;
 *@param[in] Timeout    超时时间;
 *@retval @refHAL_StatusTypeDef
 */
HAL_StatusTypeDef HAL_I2C_MemRead(I2C_HandleTypeDef *hi2c,
                                  uint16_t DevAddress,
                                  uint32_t MemAddress,
                                  uint16_t MemAddSize,
                                  uint8_t *pData,
                                  uint16_t Size,
                                  uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        hi2c->State = HAL_I2C_STATE_BUSY_RX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;

        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_MemRead(hi2c->Instance,
                                    DevAddress,
                                    MemAddress,
                                    MemAddSize,
                                    hi2c->Init.HighSpeed,
                                    hi2c->pXferBuf,
                                    hi2c->XferSize,
                                    Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            hi2c->State = HAL_I2C_STATE_READY;
            HalStatus = DrvStatusToHalStatus(DrvStatus);
            return(HalStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
 *@brief 查循方式通过指定的I2C端口发送数据.
 *
 *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
 *@param[in] DevAddress 从机地址;
 *@param[in] MemAddress 从机子地址;
 *@param[in] MemAddSize 从机子地址长度，单位字节;
 *@param[in] pData      待发送数据指针;
 *@param[in] Size       待发送数据长度;
 *@param[in] Timeout    超时时间;
 *@retval @refHAL_StatusTypeDef
 */
HAL_StatusTypeDef HAL_I2C_MemWriteIT(I2C_HandleTypeDef *hi2c,
                                     uint16_t DevAddress,
                                     uint32_t MemAddress,
                                     uint16_t MemAddSize,
                                     uint8_t *pData,
                                     uint16_t Size,
                                     uint32_t Timeout)

{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        hi2c->MemAdd = MemAddress;
        hi2c->MemAddSize = MemAddSize;
        hi2c->XferFlag = 0;
        /*中断处理函数为空*/
        hi2c->XferISR = HAL_I2C_MasterMemIRQHandler;
        hi2c->State = HAL_I2C_STATE_BUSY_MEM_SUBADD;
		
        /*发送起始条件*/        
        DevAddress &= ~0x01;
        DRV_I2C_SetDR(hi2c->Instance, DevAddress);
        _i2c_generate_start(hi2c->Instance);
		_i2c_en_it(hi2c->Instance);
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
*@brief 查循方式通过指定的I2C端口发送数据.
*
*@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
*@param[in] DevAddress 从机地址;
*@param[in] MemAddress 从机子地址;
*@param[in] MemAddSize 从机子地址长度，单位字节;
*@param[in] pData      待发送数据指针;
*@param[in] Size       待发送数据长度;
*@param[in] Timeout    超时时间;
*@retval @refHAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_MemReadIT(I2C_HandleTypeDef *hi2c,
                                    uint16_t DevAddress,
                                    uint32_t MemAddress,
                                    uint16_t MemAddSize,
                                    uint8_t *pData,
                                    uint16_t Size,
                                    uint32_t Timeout)

{
    DRV_I2C_StatusTypeDef   DrvStatus;
    HAL_StatusTypeDef HalStatus;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_RX;
        hi2c->Mode = HAL_I2C_MODE_MASTER;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        hi2c->SubAdd = DevAddress;
        hi2c->MemAdd = MemAddress;
        hi2c->MemAddSize = MemAddSize;
        hi2c->XferFlag = 1;

        /*中断处理函数为空*/
        hi2c->XferISR = HAL_I2C_MasterMemIRQHandler;
        hi2c->State = HAL_I2C_STATE_BUSY_MEM_SUBADD;

        /*发送起始条件*/
        _i2c_en_it(hi2c->Instance);
        DevAddress &= ~0x01;
        DRV_I2C_SetDR(hi2c->Instance, DevAddress);
        _i2c_generate_start(hi2c->Instance);
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HAL_OK);
}
/**
  *@brief I2C作为从机模式时中断服务.
  *
  *@param[in] hi2c                指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] BasicFlags          除高速模式之外状态;
  *@param[in] SlaveHighspeedFlags 高速模式状态;
  *@param[in] ItSource            中断源;
  *@retval 无
  */
void HAL_I2C_SlaveIRQHandler(I2C_HandleTypeDef *hi2c,
                             uint8_t BasicFlags,
                             uint8_t SlaveHighspeedFlags,
                             uint8_t ItSource)
{
    uint32_t loop = 0;
    uint8_t I2CStatus;
    uint8_t I2CHighspeedStatus;
    volatile uint8_t tmp = 0;
    uint8_t TmpItSourceFlag;
    /**************************************************************/

    /*获取中断状态*/
    I2CStatus = BasicFlags;
    I2CHighspeedStatus = SlaveHighspeedFlags;
    TmpItSourceFlag = ItSource & I2C_IT_INDEX_SLV_HSIE;

    if(I2CHighspeedStatus & I2C_FLAG_SLAVE_HIGH_SPEED)
    {
        /*write 1 to clear the flag*/
        _i2c_clr_flag_slave_high_speed(hi2c->Instance);
    }

    TmpItSourceFlag = ItSource & I2C_IT_INDEX_IEN;

    if((I2CStatus & (I2C_FLAG_RC | I2C_FLAG_TF)))
    {
        if(I2CStatus & I2C_FLAG_AASLV)
        {
            /*地址匹配了*/
            if((I2CStatus & I2C_FLAG_RXTX) != I2C_FLAG_RXTX)
            {
                /**************************************************************/
                /*处于接收模式:接收数据或者地址*/
                if((I2CStatus & I2C_FLAG_TF) != I2C_FLAG_TF)
                {
                    /*接收到的是地址*/
                    /*应答主机同时清除RC标志*/					
                    _i2c_ack(hi2c->Instance);
					 hi2c->XferCnt = 0;
                }
                else
                {
                    /*接收到的是数据*/
                    DRV_I2C_GetDR(hi2c->Instance, (hi2c->pXferBuf + hi2c->XferCnt));
					
                    hi2c->XferCnt++;
                    /*应答主机同时清除RC标志*/
                    _i2c_ack(hi2c->Instance);

                    if(hi2c->XferCnt >= hi2c->XferSize)
                    {
                        hi2c->State = HAL_I2C_STATE_READY;
                        hi2c->XferCnt = hi2c->XferSize;

                        _i2c_dis_it(hi2c->Instance);
                        //_i2c_dis_add_match_it(hi2c->Instance);
                    }
                }
            }/*接收模式*/
            /**************************************************************/
            /**************************************************************/
            else
            {
                /*发送模式*/
                DRV_I2C_SetDR(hi2c->Instance, *(hi2c->pXferBuf + hi2c->XferCnt));
                hi2c->XferCnt++;

                if(hi2c->XferCnt == hi2c->XferSize)
                {
                    hi2c->State = HAL_I2C_STATE_READY;
                    hi2c->XferCnt = hi2c->XferSize;

                    _i2c_dis_it(hi2c->Instance);
                    //_i2c_dis_add_match_it(hi2c->Instance);					
                }
            }/*发送模式*/

            /**************************************************************/
        }/*地址匹配*/
    }
}
/**
*@brief 查循方式通过指定的I2C端口发送数据.
*
*@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
*@param[in] DevAddress 从机地址;
*@param[in] pData      待发送数据指针;
*@param[in] Size       待发送数据长度;
*@param[in] Timeout    超时时间;
*@retval @ref HAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_SlaveTransmit(I2C_HandleTypeDef *hi2c,
                                        uint8_t *pData,
                                        uint16_t Size,
                                        uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus = HAL_OK;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_SLAVE;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;
        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_SlaveTransmit(hi2c->Instance,
                                          hi2c->pXferBuf,
                                          hi2c->XferSize,
                                          Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            HalStatus = DrvStatusToHalStatus(DrvStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HalStatus);
}
/**
*@brief 查循方式通过指定的I2C端口接收数据.
*
*@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
*@param[in] DevAddress 从机地址
*@param[in] pData      待接收数据指针;
*@param[in] Size       待接收数据长度;
*@param[in] Timeout    超时时间;
*@retval @ref HAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_SlaveReceive(I2C_HandleTypeDef *hi2c,
                                       uint8_t *pData,
                                       uint16_t Size,
                                       uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus = HAL_OK;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        /**/
        hi2c->State = HAL_I2C_STATE_BUSY_RX;

        hi2c->State = HAL_I2C_STATE_BUSY_RX;
        hi2c->Mode = HAL_I2C_MODE_SLAVE;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;
        /*中断处理函数为空*/
        hi2c->XferISR = 0;

        DrvStatus = DRV_I2C_SlaveReceive(hi2c->Instance,
                                         hi2c->pXferBuf,
                                         hi2c->XferSize,
                                         Timeout);

        if(DrvStatus != DRV_I2C_OK)
        {
            HalStatus = DrvStatusToHalStatus(DrvStatus);
        }

        hi2c->State = HAL_I2C_STATE_READY;
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HalStatus);
}
/**
  *@brief 中断方式通过指定的I2C端口发送数据.
  *
  *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址
  *@param[in] pData      待发送数据指针;
  *@param[in] Size       待发送数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @ref HAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_SlaveTransmitIT(I2C_HandleTypeDef *hi2c,
                                          uint8_t *pData,
                                          uint16_t Size,
                                          uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef   DrvStatus;
    HAL_StatusTypeDef HalStatus = HAL_OK;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        hi2c->State = HAL_I2C_STATE_BUSY_TX;
        hi2c->Mode = HAL_I2C_MODE_SLAVE;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        /*中断服务函数中的回调函数*/
        if(hi2c->XferISR == NULL)
        {
            hi2c->XferISR = HAL_I2C_SlaveIRQHandler;
        }

        /*中断接收时打开中断允许*/
        _i2c_en_it(hi2c->Instance);
        //_i2c_en_add_match_it(hi2c->Instance);
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HalStatus);
}
/**
  *@brief 中断方式通过指定的I2C端口接收数据.
  *
  *@param[in] hi2c       指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] DevAddress 从机地址
  *@param[in] pData      待接收数据指针;
  *@param[in] Size       待接收数据长度;
  *@param[in] Timeout    超时时间;
  *@retval @ref HAL_StatusTypeDef
*/
HAL_StatusTypeDef HAL_I2C_SlaveReceiveIT(I2C_HandleTypeDef *hi2c,
                                         uint8_t *pData,
                                         uint16_t Size,
                                         uint32_t Timeout)
{
    DRV_I2C_StatusTypeDef  DrvStatus;
    HAL_StatusTypeDef HalStatus = HAL_OK;

    /*不能双工工作，同时只能有发送或者接收*/
    if(hi2c->State == HAL_I2C_STATE_READY)
    {
        hi2c->State = HAL_I2C_STATE_BUSY_RX;
        hi2c->Mode = HAL_I2C_MODE_SLAVE;
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
        hi2c->pXferBuf = pData;
        hi2c->XferCnt = 0;
        hi2c->XferSize = Size;

        /*中断服务函数中的回调函数*/
        if(hi2c->XferISR == NULL)
        {
            hi2c->XferISR = HAL_I2C_SlaveIRQHandler;
        }

        /*中断接收时打开中断允许，此处以或的形式打开,因HAL_MspInit之中可能打开高速中断*/
        _i2c_en_it(hi2c->Instance);
        //_i2c_en_add_match_it(hi2c->Instance);
    }
    else
    {
        return(HAL_BUSY);
    }

    return(HalStatus);
}
/**
*@brief 中断方式通过指定的I2C端口接收数据.
*
*@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
*@retval 无
*@note 根据I2C主从工作模式不同以及接收发送的不同XferISR在对应接口中会变化;
*/
void HAL_I2C_IRQ(I2C_HandleTypeDef *hi2c)
{
    uint8_t BasicFlags;
    uint8_t SlaveHighspeedFlags;
    uint8_t ItSource;

    DRV_I2C_GetItFlags(hi2c->Instance, &BasicFlags, &SlaveHighspeedFlags);
    DRV_I2C_GetItSource(hi2c->Instance, &ItSource);

    if(hi2c->XferISR != NULL)
    {
        hi2c->XferISR(hi2c,
                      BasicFlags,
                      SlaveHighspeedFlags,
                      ItSource);
    }
}
/**
  *@brief 获取当前状态.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@retval 当前状态 @ref HAL_I2C_StateTypeDef
  */
HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c)
{
	return(hi2c->State);
}
/**
  *@brief 获取当前错误码.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@retval 错误码
  */
uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c)
{
	return(hi2c->ErrorCode);
}
/**
  *@brief 初始化I2C_TypeDef指定的I2C的管脚作为GPIO功能,GPIO_InitTypeDef为初始化信息如方向、上拉、输出模式、输入模式;。
  *
  *@param[in] hi2c      指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] GPIO_Init 指向GPIO_InitTypeDef结构体的指针;
  *@retval 无
  */
void  HAL_I2C_GPIOInit(I2C_TypeDef  *pi2c, GPIO_InitTypeDef *GPIO_Init)
{
    DRV_I2C_GpioInit(pi2c, GPIO_Init);
}
/**
  *@brief 复位I2C_TypeDef指定的I2C的管脚功能为默认.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] pin  I2C具体管脚;
  *- I2C_PIN_SCL;
  *- I2C_PIN_SDA;
  *@retval 无
  */
void  HAL_I2C_GPIODeInit(I2C_TypeDef  *pi2c, uint16_t Pin)
{
    DRV_I2C_GpioDeInit(pi2c, Pin);
}
/**
  *@brief 读取pin指定的I2C的管脚当电平.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] pin  I2C具体管脚;
  *- I2C_PIN_SCL;
  *- I2C_PIN_SDA;
  *@retval @ref GPIO_PinStateTypeDef
  */
GPIO_PinStateTypeDef HAL_I2C_GPIOReadPin(I2C_TypeDef *pi2c, uint16_t Pin)
{
    return(DRV_I2C_ReadPin(pi2c, Pin));
}
/**
  *@brief pin指定的I2C的管脚输出PinState指定电平.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] pin I2C具体管脚;
   *- I2C_PIN_SCL;
   *- I2C_PIN_SDA;
  *@param[in]PinState
   *- HAL_BIT_SET;
   *- HAL_BIT_RESET;
  *@retval 无
  */
void HAL_I2C_GPIOWritePin(I2C_TypeDef *pi2c, uint16_t Pin, GPIO_PinStateTypeDef PinState)
{
    DRV_I2C_WritePin(pi2c, Pin, PinState);
}
/**
  *@brief 翻转pin指定的I2C的管脚电平.
  *
  *@param[in] hi2c 指向I2C_HandleTypeDef结构体的指针,此结构体包含了I2C模块的配置信息;
  *@param[in] pin  I2C具体管脚;
  *- I2C_PIN_SCL;
  *- I2C_PIN_SDA;
  *@retval 无
  */
void HAL_I2C_GPIOTogglePin(I2C_TypeDef *pi2c, uint16_t Pin)
{
    DRV_I2C_TogglePin(pi2c, Pin);
}
