/**
******************************************************************************************************************************************************************************************
*@file                       cpu_i2c_test.c
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#include "cpu_i2c.h"

#define I2C_SPEED_STANDARD_MAX_FREQ							(100000)
#define I2C_SPEED_FAST_MAX_FREQ								(400000)
#define I2C_SPEED_HIGH_MAX_FREQ								(3400000)

#define I2C_IC_CON_SPEED_Mask								(I2C_IC_CON_SPEED_0 | I2C_IC_CON_SPEED_1)
#define I2C_IC_CON_SPEED_STANDARD							(I2C_IC_CON_SPEED_0)
#define I2C_IC_CON_SPEED_FAST								(I2C_IC_CON_SPEED_1)
#define I2C_IC_CON_SPEED_HIGH								(I2C_IC_CON_SPEED_0 | I2C_IC_CON_SPEED_1)

#define I2C_SPEED_FAST_SPIKE_MAX							(50)		//in fast mode, the max of spikes pulse is 50ns
#define I2C_SPEED_HIGH_SPIKE_MAX							(10)		//in HIGHT mode, the max of spikes pulse is 10ns

#define I2C_SPEED_FAST_SPIKE_Hz_MAX							(20000000)		//in fast mode, the max of spikes pulse is 20MHz
#define I2C_SPEED_HIGH_SPIKE_Hz_MAX							(100000000)		//in HIGHT mode, the max of spikes pulse is 100MHz

#define I2C_WAIT_LOOP			1000
/*******************************************************************************
* 函数名   : i2c_init.
* 说明     : i2c初始化
* 参数     : -i2cx,             I2C,参考 cpu.h 定义
             -i2c_init_struct,  I2C初始化参数配置，参考 i2c_init_type_def 定义
* 返回值   : None.
* 示例     : i2c_init(I2C,&i2c_init_struct);
*******************************************************************************/
void i2c_init(i2c_type_def * i2cx,i2c_init_type_def* i2c_init_struct)
{
	uint32_t tmp_reg = 0;
	uint32_t tmp_speed = 0;
	uint32_t tmp_clock_count = 0;
	uint32_t tmp_duty_cycle = 0;
	uint32_t tmp_duty_cycle_tlow = 0;
	uint32_t tmp_duty_cycle_thigh = 0;
	uint32_t tmp_spike_count_speed_fast = 0;
	uint32_t tmp_spike_count_speed_high = 0;

	i2cx->IC_ENABLE = 0;
	/*---------------------------- i2cx Clock Control Configuration -----------------------*/
	/*                             i2cx IC_*_SCL_HCNT Configuration                        */
	/*                             i2cx IC_*_SCL_LCNT Configuration                        */
	/*                             i2cx IC_*_SPKLEN Configuration                          */
	/*-------------------------------------------------------------------------------------*/
	tmp_duty_cycle_tlow = (i2c_init_struct->i2c_duty_cycle & 0xFF00) >> 8;
	tmp_duty_cycle_thigh = i2c_init_struct->i2c_duty_cycle & 0x00FF;
	tmp_duty_cycle = tmp_duty_cycle_tlow + tmp_duty_cycle_thigh;

	tmp_clock_count = ((16000000 - 1) + i2c_init_struct->i2c_clock_speed) / i2c_init_struct->i2c_clock_speed;
	tmp_spike_count_speed_fast = ((16000000 - 1) + I2C_SPEED_FAST_SPIKE_Hz_MAX) / I2C_SPEED_FAST_SPIKE_Hz_MAX;
	tmp_spike_count_speed_high = ((16000000 - 1) + I2C_SPEED_HIGH_SPIKE_Hz_MAX) / I2C_SPEED_HIGH_SPIKE_Hz_MAX;

	if (i2c_init_struct->i2c_clock_speed <= I2C_SPEED_STANDARD_MAX_FREQ)
	{
		tmp_speed = I2C_IC_CON_SPEED_STANDARD;
	} 
	else if (i2c_init_struct->i2c_clock_speed <= I2C_SPEED_FAST_MAX_FREQ)
	{
		tmp_speed = I2C_IC_CON_SPEED_FAST;
	}
	else if (i2c_init_struct->i2c_clock_speed <= I2C_SPEED_HIGH_MAX_FREQ)
	{
		tmp_speed = I2C_IC_CON_SPEED_HIGH;
	}
	else
	{
		tmp_speed = I2C_IC_CON_SPEED_STANDARD;
	}

	switch(tmp_speed)
	{
	case I2C_IC_CON_SPEED_STANDARD:
		// Standard Speed Spike in I2C Bus Specification is N/A (Not Applicable)
		// The following code of Spike setting depand on SCPU I2C IP Specification
		if (tmp_spike_count_speed_fast)
			i2cx->IC_FS_SPKLEN = tmp_spike_count_speed_fast;
		else
			i2cx->IC_FS_SPKLEN = 1;
		i2cx->IC_SS_SCL_HCNT = (tmp_clock_count + 1) / 2 - i2cx->IC_FS_SPKLEN;
		i2cx->IC_SS_SCL_LCNT = (tmp_clock_count + 1) / 2;
		break;
	case I2C_IC_CON_SPEED_FAST:
		if (tmp_spike_count_speed_fast)
			i2cx->IC_FS_SPKLEN = tmp_spike_count_speed_fast;
		else
			i2cx->IC_FS_SPKLEN = 1;
		i2cx->IC_FS_SCL_HCNT = ((tmp_clock_count + tmp_duty_cycle) / tmp_duty_cycle) * tmp_duty_cycle_thigh - i2cx->IC_FS_SPKLEN;
		i2cx->IC_FS_SCL_LCNT = ((tmp_clock_count + tmp_duty_cycle) / tmp_duty_cycle) * tmp_duty_cycle_tlow;
		break;
	case I2C_IC_CON_SPEED_HIGH:
		if (tmp_spike_count_speed_high)
			i2cx->IC_HS_SPKLEN = tmp_spike_count_speed_high;
		else
			i2cx->IC_HS_SPKLEN = 1;
		i2cx->IC_HS_SCL_HCNT = ((tmp_clock_count + tmp_duty_cycle) / tmp_duty_cycle) * tmp_duty_cycle_thigh - i2cx->IC_HS_SPKLEN;
		i2cx->IC_HS_SCL_LCNT = ((tmp_clock_count + tmp_duty_cycle) / tmp_duty_cycle) * tmp_duty_cycle_tlow;
		break;
	}

/*---------------------------- i2cx IC_CON Configuration -----------------------*/
	tmp_reg = i2cx->IC_CON;

	tmp_reg &= ~I2C_IC_CON_SPEED_Mask;
	tmp_reg |= tmp_speed;

	tmp_reg &= ~(I2C_IC_CON_MASTER_MODE | I2C_IC_CON_SLAVE_DISABLE);
	if (i2c_init_struct->i2c_mode == I2C_Mode_Master)
	{
		tmp_reg |= (I2C_IC_CON_MASTER_MODE | I2C_IC_CON_SLAVE_DISABLE);
	}
	else if (i2c_init_struct->i2c_mode == I2C_Mode_Slave)
	{
		tmp_reg &= ~(I2C_IC_CON_MASTER_MODE | I2C_IC_CON_SLAVE_DISABLE);
	}

	if (I2C_AcknowledgedAddress_10bit == i2c_init_struct->i2c_acknowledged_address)
	{
		tmp_reg |= I2C_IC_CON_10BITADDR_SLAVE;
	}
	else
	{
		tmp_reg &= ~I2C_IC_CON_10BITADDR_SLAVE;
	}

	if (DISABLE != i2c_init_struct->i2c_generate_restart_enable)
	{
		tmp_reg |= I2C_IC_CON_RESTART_EN;
	}
	else
	{
		tmp_reg &= ~I2C_IC_CON_RESTART_EN;
	}

	i2cx->IC_CON = tmp_reg;


/*---------------------------- i2cx IC_SDA_SETUP Configuration -----------------------*/
	i2cx->IC_SDA_SETUP = (i2c_init_struct->i2c_sda_setup_time & I2C_IC_SDA_SETUP);

/*---------------------------- i2cx IC_SDA_HOLD Configuration -----------------------*/
	i2cx->IC_SDA_HOLD = (i2c_init_struct->i2c_sda_hold_time & I2C_IC_SDA_HOLD);


/*---------------------------- i2cx IC_TAR Configuration -----------------------*/

	tmp_reg = i2cx->IC_TAR;

	if (I2C_TargetAddressMode_10bit == i2c_init_struct->i2c_target_address_mode)
	{
		tmp_reg |= I2C_IC_TAR_10BITADDR_MASTER;
		tmp_reg &= ~I2C_IC_TAR_TAR;
		tmp_reg |= (i2c_init_struct->i2c_target_address & 0x03FF);
	} 
	else
	{
		tmp_reg &= ~I2C_IC_TAR_10BITADDR_MASTER;
		tmp_reg &= ~I2C_IC_TAR_TAR;
		tmp_reg |= (i2c_init_struct->i2c_target_address & 0x007F);
	}

	i2cx->IC_TAR = tmp_reg;

/*---------------------------- i2cx IC_SAR Configuration -----------------------*/
	i2cx->IC_SAR = i2c_init_struct->i2c_own_address;

/*---------------------------- i2cx IC_RX_TL Configuration -----------------------*/
/*---------------------------- i2cx IC_TX_TL Configuration -----------------------*/
	i2cx->IC_RX_TL = i2c_init_struct->i2c_rx_fifo_full_threshold;
	i2cx->IC_TX_TL = i2c_init_struct->i2c_tx_fifo_empty_threshold;
	
/*---------------------------- i2cx IC_INTR_MASK Configuration -----------------------*/
	i2cx->IC_INTR_MASK = 0;
}


/*******************************************************************************
* 函数名   : i2c_struct_init.
* 说明     : i2c结构体初始化
* 参数     : -i2c_init_struct,    I2C初始化参数配置，参考 i2c_init_type_def 定义
* 返回值   : None.
* 示例     : i2c_struct_init(&i2c_init_struct);
*******************************************************************************/
void i2c_struct_init(i2c_init_type_def* i2c_init_struct)
{
	i2c_init_struct->i2c_clock_speed = I2C_ClockSpeed_100KHz;
	i2c_init_struct->i2c_mode = I2C_Mode_Master;
	i2c_init_struct->i2c_duty_cycle = I2C_DutyCycle_1;
	/* i2c_sda_setup_time = 0x64 is RESET value*/
	i2c_init_struct->i2c_sda_setup_time = 0x64;
	/* i2c_sda_hold_time = 0x0001 is RESET value*/
	i2c_init_struct->i2c_sda_hold_time = 0x0001;
	/* i2c_target_address = 0x55 is RESET value*/
	i2c_init_struct->i2c_target_address = 0x55;
	/* i2c_target_address_mode = I2C_TargetAddressMode_10bit is RESET value*/
	i2c_init_struct->i2c_target_address_mode = I2C_TargetAddressMode_7bit;
	/* i2c_own_address = 0x55 is RESET value*/
	i2c_init_struct->i2c_own_address = 0x55;
	/* i2c_acknowledged_address = I2C_AcknowledgedAddress_10bit is RESET value*/
	i2c_init_struct->i2c_acknowledged_address = I2C_AcknowledgedAddress_7bit;
	i2c_init_struct->i2c_rx_fifo_full_threshold = I2C_RXFIFOFullThreshold_1;
	i2c_init_struct->i2c_tx_fifo_empty_threshold = I2C_TXFIFOEmptyThreshold_0;
	i2c_init_struct->i2c_generate_restart_enable = ENABLE;
}


/*******************************************************************************
* 函数名   : i2c_set_target_address.
* 说明     : 设置i2c目标地址
* 参数     : -i2cx,           		I2C,参考 cpu.h 定义
			 -target_address，		目标地址
			 -target_address_mode， 目标地址模式，参考 cpu_i2c.h 
* 返回值   : None.
* 示例     : i2c_struct_init(I2C,0xA0,I2C_TargetAddressMode_7bit);
*******************************************************************************/
void i2c_set_target_address(i2c_type_def* i2cx, uint32_t target_address, uint32_t target_address_mode)
{
	uint32_t tmp_reg = 0;
	tmp_reg = i2cx->IC_TAR;

	if (I2C_TargetAddressMode_10bit == target_address_mode)
	{
		tmp_reg |= I2C_IC_TAR_10BITADDR_MASTER;
		tmp_reg &= ~I2C_IC_TAR_TAR;
		tmp_reg |= (target_address & 0x03FF);
	} 
	else
	{
		tmp_reg &= ~I2C_IC_TAR_10BITADDR_MASTER;
		tmp_reg &= ~I2C_IC_TAR_TAR;
		tmp_reg |= (target_address & 0x007F);
	}

	i2cx->IC_TAR = tmp_reg;
}

/*******************************************************************************
* 函数名   : i2c_cmd.
* 说明     : i2c使能
* 参数     : -i2cx,           		I2C,参考 cpu.h 定义
			 -new_state，			使能或不使能，参考 functional_state_t 定义		
* 返回值   : None.
* 示例     : i2c_cmd(I2C,ENABLE);
*******************************************************************************/
void i2c_cmd(i2c_type_def * i2cx,functional_state_t new_state)
{
	/* Check the parameters */
	if(new_state != DISABLE)
		i2cx->IC_ENABLE = 1;
	else
		i2cx->IC_ENABLE = 0;
}


/*******************************************************************************
* 函数名   : i2c_dma_init.
* 说明     : i2c dma初始化
* 参数     : -i2cx,           		    I2C,参考 cpu.h 定义
			 -i2c_dma_init_struct，	    I2C dma结构体参数配置，参考 i2c_dma_init_type_def 定义
* 返回值   : None.
* 示例     : i2c_dma_init(I2C,&i2c_dma_init_struct);
*******************************************************************************/
void i2c_dma_init(i2c_type_def* i2cx, i2c_dma_init_type_def* i2c_dma_init_struct)
{
	/* Check the parameters */
	i2cx->IC_DMA_RDLR = i2c_dma_init_struct->i2c_dma_receive_level;
	i2cx->IC_DMA_TDLR = i2c_dma_init_struct->i2c_dma_transmit_level;
	if (DISABLE != i2c_dma_init_struct->i2c_dma_encmd)
	{
		i2cx->IC_DMA_CR |= i2c_dma_init_struct->i2c_dma_req;
	} 
	else
	{
		i2cx->IC_DMA_CR &= ~i2c_dma_init_struct->i2c_dma_req;
	}
}

/*******************************************************************************
* 函数名   : i2c_dma_init.
* 说明     : i2c dma结构体初始化
* 参数     : -i2c_dma_init_struct，	    I2C dma参数配置，参考 i2c_dma_init_type_def 定义
* 返回值   : None.
* 示例     : i2c_dma_struct_init(&i2c_dma_init_struct);
*******************************************************************************/
void i2c_dma_struct_init(i2c_dma_init_type_def* i2c_dma_init_struct)
{

	i2c_dma_init_struct->i2c_dma_req = I2C_DMAReq_Rx | I2C_DMAReq_Tx;
	/* Initialize the i2c_dma_receive_level member */
	i2c_dma_init_struct->i2c_dma_receive_level = I2C_DMAReceiveLevel_4;
	/* Initialize the i2c_dma_transmit_level member */
	i2c_dma_init_struct->i2c_dma_transmit_level = I2C_DMATransmitLevel_4;

	i2c_dma_init_struct->i2c_dma_encmd = DISABLE;

}

/*******************************************************************************
* 函数名   : i2c_dma_init.
* 说明     : i2c dma使能
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -i2c_dma_req，	    I2C DMA请求
			 -new_state			使能或不使能，参考 functional_state_t 定义
* 返回值   : None.
* 示例     : i2c_dma_cmd(I2C,I2C_DMAReq_Rx,ENABLE);
*******************************************************************************/
void i2c_dma_cmd(i2c_type_def* i2cx, uint32_t i2c_dma_req, functional_state_t new_state)
{
	/* Check the parameters */
	if (DISABLE != new_state)
	{
		i2cx->IC_DMA_CR |= i2c_dma_req;
	} 
	else
	{
		i2cx->IC_DMA_CR &= ~i2c_dma_req;
	}
}

/*******************************************************************************
* 函数名   : i2c_set_sda_setup_time.
* 说明     : 设置i2c sda调整时间
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -pclk_cycles，	    延时时间
* 返回值   : None.
* 示例     : i2c_dma_cmd(I2C,10);
*******************************************************************************/
void i2c_set_sda_setup_time(i2c_type_def * i2cx,uint32_t pclk_cycles)
{
	/* Check the parameters */
	if (RESET == i2c_is_enable(i2cx))
	{
		i2cx->IC_SDA_SETUP = (pclk_cycles & I2C_IC_SDA_SETUP);
	}
}


void i2c_set_sda_hold_time(i2c_type_def * i2cx,uint32_t pclk_cycles)
{
	/* Check the parameters */
	if (RESET == i2c_is_enable(i2cx))
	{
		i2cx->IC_SDA_HOLD = (pclk_cycles & I2C_IC_SDA_HOLD);
	}
}

/*******************************************************************************
* 函数名   : i2c_it_config.
* 说明     : i2c中断配置
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -i2c_it，	        中断类型
			 -new_state			使能或不使能，参考 functional_state_t 定义
* 返回值   : None.
* 示例     : i2c_it_config(I2C,I2C_IT_RXF | I2C_IT_TXE | I2C_IT_RD_REQ | I2C_IT_RX_DONE,ENABLE);
*******************************************************************************/
void i2c_it_config(i2c_type_def * i2cx,uint32_t i2c_it, functional_state_t new_state)
{
	/* Check the parameters */
	if(new_state != DISABLE)
	{
		i2cx->IC_INTR_MASK |= i2c_it;
	}
	else
	{
		i2cx->IC_INTR_MASK &= ~i2c_it;
	}
}


/*******************************************************************************
* 函数名   : i2c_get_it_status.
* 说明     : 获取i2c中断状态
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -i2c_it，	        中断类型
* 返回值   : -SET ： 产生相应中断
			 -RESET：未产生相应中断
* 示例     : i2c_get_it_status(I2C,I2C_IT_TXE);
*******************************************************************************/
itstatus i2c_get_it_status(i2c_type_def * i2cx,uint32_t i2c_it)
{
	itstatus bitStatus = RESET;

	if((i2cx->IC_INTR_STAT & i2c_it) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	return bitStatus;
}

/*******************************************************************************
* 函数名   : i2c_get_raw_it_status.
* 说明     : 获取i2c原中断状态
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -i2c_it，	        中断类型
* 返回值   : None.
* 示例     : i2c_get_raw_it_status(I2C,I2C_IT_TXE);
*******************************************************************************/
itstatus i2c_get_raw_it_status(i2c_type_def* i2cx,uint32_t i2c_it)
{
	itstatus bitStatus = RESET;

	if((i2cx->IC_RAW_INTR_STAT & i2c_it) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	return bitStatus;
}

/*******************************************************************************
* 函数名   : i2c_clear_it_pending_bit.
* 说明     : 清除i2c中断标志位
* 参数     : -i2cx				I2C,参考 cpu.h 定义
			 -i2c_it，	        中断类型
* 返回值   : None.
* 示例     : i2c_clear_it_pending_bit(I2C,I2C_IT_TXE);
*******************************************************************************/
void i2c_clear_it_pending_bit(i2c_type_def * i2cx,uint32_t i2c_it)
{
	if (I2C_IT_RXUDF | i2c_it)
	{
		i2cx->IC_CLR_RX_UNDER;
	}
	if (I2C_IT_RXOVF | i2c_it)
	{
		i2cx->IC_CLR_RX_OVER;
	}
	if (I2C_IT_TXOVF | i2c_it)
	{
		i2cx->IC_CLR_TX_OVER;
	}
	if (I2C_IT_RD_REQ | i2c_it)
	{
		i2cx->IC_CLR_RD_REQ;
	}
	if (I2C_IT_TX_ABRT | i2c_it)
	{
		i2cx->IC_CLR_TX_ABRT;
	}
	if (I2C_IT_RX_DONE | i2c_it)
	{
		i2cx->IC_CLR_RX_DONE;
	}
	if (I2C_IT_ACTIVITY | i2c_it)
	{
		i2cx->IC_CLR_ACTIVITY;
	}
	if (I2C_IT_STOP_DET | i2c_it)
	{
		i2cx->IC_CLR_STOP_DET;
	}
	if (I2C_IT_START_DET | i2c_it)
	{
		i2cx->IC_CLR_START_DET;
	}
	if (I2C_IT_GEN_CALL | i2c_it)
	{
		i2cx->IC_CLR_GEN_CALL;
	}
}

/*******************************************************************************
* 函数名   : i2c_is_enable.
* 说明     : i2c使能
* 参数     : -i2cx						I2C,参考 cpu.h 定义
* 返回值   : -bitStatus = SET.   		I2C已经使能
			 -bitStatus = RESET			I2C未使能
* 示例     : i2c_is_enable(ENABLE);
*******************************************************************************/
flag_status i2c_is_enable(i2c_type_def * i2cx)
{
	itstatus bitStatus = RESET;

	if((i2cx->IC_ENABLE & I2C_IC_ENABLE_ENABLE) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	return bitStatus;
}

/*******************************************************************************
* 函数名   : i2c_get_flag_status.
* 说明     : 获取i2c标志状态
* 参数     : -i2cx				  I2C,参考 cpu.h 定义
			 -I2C_FLAG			  I2C状态
* 返回值   : -bitStatus = SET.    相应的状态产生	
			 -bitStatus = RESET	  相应的状态未产生		
* 示例     : i2c_get_flag_status(I2C,I2C_FLAG_TXE);
*******************************************************************************/
flag_status i2c_get_flag_status(i2c_type_def * i2cx,uint32_t I2C_FLAG)
{
	itstatus bitStatus = RESET;
	
	if((i2cx->IC_STATUS & I2C_FLAG) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	return bitStatus;
}

/*******************************************************************************
* 函数名   : i2c_get_flag_status.
* 说明     : 获取i2c标志状态
* 参数     : -i2cx.				I2C,参考 cpu.h 定义
* 返回值   : I2C STATUS 寄存器值.
* 示例     : i2c_get_flag_status(I2C);
*******************************************************************************/
uint32_t i2c_get_flag_status_reg(i2c_type_def * i2cx)
{
	return i2cx->IC_STATUS;
}

/*******************************************************************************
* 函数名   : i2c_get_tx_abort_source.
* 说明     : 获取i2c发送中断源
* 参数     : -i2cx						I2C,参考 cpu.h 定义
			 -i2c_tx_abrt				I2C 中断源类型
* 返回值   : -bitStatus = SET.   		相应中断产生
			 -bitStatus = RESET			相应中断未产生
* 示例     : i2c_get_tx_abort_source(I2C,I2C_TX_ABRT_7BIT_ADDR_NOACK);
*******************************************************************************/
flag_status i2c_get_tx_abort_source(i2c_type_def * i2cx,uint32_t i2c_tx_abrt)
{
	itstatus bitStatus = RESET;

	if((i2cx->IC_TX_ABRT_SOURCE & i2c_tx_abrt) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	return bitStatus;
}

/*******************************************************************************
* 函数名   : i2c_get_tx_abort_source_reg.
* 说明     : 获取I2C中断源寄存器值
* 参数     : -i2cx					I2C,参考 cpu.h 定义
* 返回值   : I2C中断源寄存器值
* 示例     : i2c_get_tx_abort_source_reg(I2C);
*******************************************************************************/
uint32_t i2c_get_tx_abort_source_reg(i2c_type_def * i2cx)
{
	return i2cx->IC_TX_ABRT_SOURCE;
}


/*******************************************************************************
* 函数名   : i2c_get_i2c_mode.
* 说明     : 获取i2c模式
* 参数     : -i2cx								  I2C,参考 cpu.h 定义
* 返回值   : -2c_mode_ret = I2C_Mode_Master.      I2C作为Master端
			 -i2c_mode_ret = I2C_Mode_Slave.	  I2C作为Slave端
* 示例     : i2c_get_i2c_mode(I2C);
*******************************************************************************/
i2c_mode_type_def i2c_get_i2c_mode(i2c_type_def* i2cx)
{
	i2c_mode_type_def i2c_mode_ret;

	if ((i2cx->IC_CON & I2C_IC_CON_MASTER_MODE) && (i2cx->IC_CON & I2C_IC_CON_SLAVE_DISABLE))
	{
		i2c_mode_ret = I2C_Mode_Master;
	}
	else
	{
		i2c_mode_ret = I2C_Mode_Slave;
	}
	return i2c_mode_ret;
}

/*******************************************************************************
* 函数名   : i2c_write_data_to_dr.
* 说明     : i2c写数据到dr
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -ExtendData					  数据
* 返回值   : None
* 示例     : i2c_write_data_to_dr(I2C,0x36);
*******************************************************************************/
void i2c_write_data_to_dr(i2c_type_def* i2cx, uint16_t ExtendData)
{
	i2cx->IC_DATA_CMD = (ExtendData & 0x07FF);
}

/*******************************************************************************
* 函数名   : i2c_read_data_from_dr.
* 说明     : 从I2C的DAT寄存器中读取数据
* 参数     : -i2cx					   I2C,参考 cpu.h 定义
* 返回值   : I2C DAT寄存值
* 示例     : i2c_read_data_from_dr(I2C);
*******************************************************************************/
uint8_t i2c_read_data_from_dr(i2c_type_def* i2cx)
{
	return (uint8_t)(i2cx->IC_DATA_CMD & 0x00FF);
}

/*******************************************************************************
* 函数名   : i2c_extend_data.
* 说明     : i2c扩展数据
* 参数     : -data						数据
			 -data_cmd					命令类型：读、写
			 -data_condition			end数据类型	
* 返回值   : I2C end数据类型
* 示例     : i2c_read_data_from_dr(I2C,I2C_DataEndCondition_None);
*******************************************************************************/
uint16_t i2c_extend_data(uint8_t data, i2c_data_cmd_type_def data_cmd, i2c_data_end_condition_type_def data_condition)
{
	uint16_t tmpRet;

	tmpRet = 0;
	tmpRet = (uint16_t)data;

	/*
	 *	Extend data With Read/Write Operation 
	 */
	switch((uint32_t)data_cmd)
	{
	case I2C_DataCMD_Read:
		{
			tmpRet |= I2C_IC_DATA_CMD_CMD;
			break;
		}
	case I2C_DataCMD_Write:
		{
			tmpRet &= ~I2C_IC_DATA_CMD_CMD;
			break;
		}
	}
	
	/*
	 *	Extend data With End Condition
	 */
	switch((uint32_t)data_condition)
	{
	case I2C_DataEndCondition_Stop:
		{
			tmpRet |= I2C_IC_DATA_CMD_STOP;
			break;
		}
	case I2C_DataEndCondition_Restart:
		{
			tmpRet |= I2C_IC_DATA_CMD_RESTART;
			break;
		}
	case I2C_DataEndCondition_None:
		{
			tmpRet &= ~(I2C_IC_DATA_CMD_STOP | I2C_IC_DATA_CMD_RESTART);
			break;
		}
	}


	return tmpRet;
}

/*******************************************************************************
* 函数名   : i2c_send_data.
* 说明     : i2c发送数据
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -data_condition				  end位数据类型	
* 返回值   : None.
* 示例     : i2c_send_data(I2C,0xAA);
*******************************************************************************/
void i2c_send_data(i2c_type_def* i2cx, uint8_t data, i2c_data_end_condition_type_def data_condition)
{
	uint32_t tmp_reg;

	tmp_reg = 0;

 	if (I2C_Mode_Master == i2c_get_i2c_mode(i2cx))
	{
		tmp_reg = i2c_extend_data(data, I2C_DataCMD_Write ,data_condition);
	}
	else
	{
		tmp_reg = i2c_extend_data(data, I2C_DataCMD_Write ,I2C_DataEndCondition_None);
	}
	i2c_write_data_to_dr(i2cx,  tmp_reg);
}

/*******************************************************************************
* 函数名   : i2c_master_generate_receive_scl.
* 说明     : 生成master接收时序
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -data_condition				  end 位数据类型	
* 返回值   : 接收的数据.					
* 示例     :i2c_master_generate_receive_scl(i2cx, I2C_DataEndCondition_None);
*******************************************************************************/
void i2c_master_generate_receive_scl(i2c_type_def* i2cx, i2c_data_end_condition_type_def data_condition)
{
	uint16_t tmp_reg;
	
	tmp_reg = 0;
	tmp_reg = i2c_extend_data(tmp_reg, I2C_DataCMD_Read ,data_condition);
	i2c_write_data_to_dr(i2cx,  tmp_reg);
}

/*******************************************************************************
* 函数名   : i2c_receive_data.
* 说明     : i2c接收数据
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -data_condition				  end 位数据类型	
* 返回值   : 接收的数据.					
* 示例     : i2c_receive_data(I2C,I2C_DataEndCondition_Stop);
*******************************************************************************/
uint8_t i2c_receive_data(i2c_type_def* i2cx, i2c_data_end_condition_type_def data_condition)
{
	uint32_t loop = 0;
	uint8_t tmpRet;
	assert_param(IS_I2C_ALL_PERIPH(i2cx));
	assert_param(IS_I2C_DATA_END_CONDITION(data_condition));

	tmpRet = 0;
	if (I2C_Mode_Master == i2c_get_i2c_mode(i2cx))
	{
		while(RESET == (i2c_get_flag_status(i2cx, I2C_FLAG_TXNF))){
			if(loop ++ > I2C_WAIT_LOOP) return 0;
		}
		i2c_master_generate_receive_scl(i2cx, data_condition);
		loop = 0;
		while(RESET == (i2c_get_flag_status(i2cx, I2C_FLAG_RXNE))){
			if(loop ++ > I2C_WAIT_LOOP) return 0;
		}
		tmpRet = (uint8_t)i2c_read_data_from_dr(i2cx);
	}
	return tmpRet;
}

/*******************************************************************************
* 函数名   : i2c_send_bytes.
* 说明     : i2c发送字节
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -data_				  			  数据	
			 -data_len				          数据长度	
			 -data_condition				  end位数据类型	
* 返回值   : -tmpRet.					
* 示例     : i2c_receive_data(I2C,I2C_DataEndCondition_None);
*******************************************************************************/
void i2c_send_bytes(i2c_type_def* i2cx, uint8_t* data, uint32_t data_len, i2c_data_end_condition_type_def data_condition)
{
	uint32_t loop = 0;
	assert_param(IS_I2C_ALL_PERIPH(i2cx));
	assert_param(IS_I2C_DATA_END_CONDITION(data_condition));
	while(data_len)
	{
		while(RESET == (i2c_get_flag_status(i2cx, I2C_FLAG_TXNF))){
			if(loop ++ > I2C_WAIT_LOOP) return;
		}

		if (data_len == 1)
		{
			i2c_send_data(i2cx, *data, data_condition);
		}
		else
		{
			i2c_send_data(i2cx, *data, I2C_DataEndCondition_None);		//it is same as I2C_SendData_Slave
		}
		data++;
		data_len--;
	}
}

/*******************************************************************************
* 函数名   : i2c_receive_bytes.
* 说明     : i2c接收字节
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -data_				  			  数据	
			 -data_len				          数据长度	
			 -data_condition				  end位数据类型	
* 返回值   : None.					
* 示例     : i2c_receive_data(I2C,I2C_DataEndCondition_None);
*******************************************************************************/
void i2c_receive_bytes(i2c_type_def* i2cx, uint8_t* data, uint32_t data_len, i2c_data_end_condition_type_def data_condition)
{
	uint32_t loop = 0;
	
	while (RESET != i2c_get_flag_status(i2cx, I2C_FLAG_RXNE)){
		i2cx->IC_DATA_CMD;
		if(loop ++ > I2C_WAIT_LOOP) return;
	}
	
	loop = 0;

	while(data_len)
	{
		if (RESET == (i2c_get_flag_status(i2cx, I2C_FLAG_TXNF))){
			if(loop ++ > I2C_WAIT_LOOP) return;
			continue;
		}

		if (I2C_Mode_Master == i2c_get_i2c_mode(i2cx))
		{
			if (data_len == 1)
			{
				i2c_master_generate_receive_scl(i2cx, data_condition);
			}
			else
			{
				i2c_master_generate_receive_scl(i2cx, I2C_DataEndCondition_None);
			}
		}
		loop = 0;

		while(RESET == (i2c_get_flag_status(i2cx, I2C_FLAG_RXNE))){
			if(loop ++ > I2C_WAIT_LOOP) return;
		}
		
		*data = (uint8_t)i2c_read_data_from_dr(i2cx);
		data++;
		data_len--;
	}
}

/*******************************************************************************
* 函数名   : i2c_slave_general_nack_only_cmd.
* 说明     : i2c从机响应使能
* 参数     : -i2cx							  I2C,参考 cpu.h 定义
			 -new_state				  		  使能或不使能，参考 functional_state_t 定义	
* 返回值   : None.					
* 示例     : i2c_slave_general_nack_only_cmd(I2C,ENABLE);
*******************************************************************************/
void i2c_slave_general_nack_only_cmd(i2c_type_def* i2cx, functional_state_t new_state)
{
	assert_param(IS_I2C_ALL_PERIPH(i2cx));
	assert_param(IS_FUNCTIONAL_STATE(new_state));
	if (DISABLE != new_state)
	{
		i2cx->IC_SLV_DATA_NACK_ONLY |= I2C_IC_SLV_DATA_NACK_ONLY;
	} 
	else
	{
		i2cx->IC_SLV_DATA_NACK_ONLY &= ~I2C_IC_SLV_DATA_NACK_ONLY;
	}
}


