/******************************************************************************
文 件 名:Simulated_IIC_Master.c
功能描述:IO端口模拟的IIC(I2C)主机函数库文件
作    者:张暄
版    本:V1.0
日    期:2016.12.21
******************************************************************************/

#include "LED_Driver\Simulated_IIC_2_Master.h"
#include "Components.h"
#include "Application.h"

unsigned char u8SimulatedIIC2ReceivedACK;

/******************************************************************************
函数名:IIC_Init
功  能:初始化IIC总线
参  数:无
返回值:无
******************************************************************************/
void Simulated_IIC_2_Init(void)
{
	
	RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();


	RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SDA_DIR = 0; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;
}

/******************************************************************************
函数名:IIC_Start
功  能:在IIC总线上发送起始信号,发起一次IIC通信
参  数:无
返回值:无
******************************************************************************/
void Simulated_IIC_2_Start(void)
{
	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;

	RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SDA_DIR = 0; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SDA_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);
	//SIMULATED_IIC_2_SDA_DIR = 1; //SDA输出0,此时SDA = 0
	//SIMULATED_IIC_2_OUT_SDA = 0;
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);
	//SIMULATED_IIC_2_SCL_DIR = 1; //SCL输出0,此时SCL = 0
	//SIMULATED_IIC_2_SCL = 0;
	Simulated_IIC_2_Delay();
}

/******************************************************************************
函数名:IIC_Stop
功  能:在IIC总线上发送停止信号,终止当前IIC通信
参  数:无
返回值:无
******************************************************************************/
void Simulated_IIC_2_Stop(void)
{
	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;

	RTE_GPIO_Config(IIC_SDA_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);
	//SIMULATED_IIC_2_SDA_DIR = 1; //SDA输出0,此时SDA = 0
	//SIMULATED_IIC_2_OUT_SDA = 0;
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);
	//SIMULATED_IIC_2_SDA_DIR = 0; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();
}

/******************************************************************************
函数名:IIC_Transmit_Data
功  能:向IIC总线上发送1字节数据
参  数:Data:发送的数据
返回值:总线上器件的确认(ACK)  0 - ACK  1 - NAK
******************************************************************************/
void Simulated_IIC_2_Transmit_Data(unsigned char Data)
{
	unsigned char i;

	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;

	//主机发送器件地址
	for (i = 0; i < 8; i++)
	{
		if (Data & 0x80)
			RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);//sda线上是1
			//SIMULATED_IIC_2_SDA_DIR = 0; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
		else
		{
			RTE_GPIO_Config(IIC_SDA_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//sda线上是0
			//SIMULATED_IIC_2_SDA_DIR = 1; //SDA输出0,此时SDA = 0
			//SIMULATED_IIC_2_OUT_SDA = 0;
		}
		Simulated_IIC_2_Delay();
		Simulated_IIC_2_Delay();

		RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);//读取sda上的数据
		//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
		Simulated_IIC_2_Delay();
		Simulated_IIC_2_Delay();

		RTE_GPIO_Config(IIC_SCL_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//拉低scl,允许sda变化
		//SIMULATED_IIC_2_SCL_DIR = 1; //SCL输出0,此时SCL = 0
		//SIMULATED_IIC_2_SCL = 0;
		Simulated_IIC_2_Delay();

		Data <<= 1;
	}

	//主机接收应答
	RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);//主机释放总线,从机在sda发送数据
	//SIMULATED_IIC_2_SDA_DIR = 0; //设置SDA为输入状态
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);//scl高电平,为了读取从机应答
	//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();
 
	u8SimulatedIIC2ReceivedACK = RTE_GPIO_Get_Level(IIC_SDA_27030);//读取从机应答
	//u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_IN_SDA;

	RTE_GPIO_Config(IIC_SCL_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//拉低scl,允许sda变化
	//SIMULATED_IIC_2_SCL_DIR = 1; //SCL输出0,此时SCL = 0
	//SIMULATED_IIC_2_SCL = 0;
	Simulated_IIC_2_Delay();
}

/******************************************************************************
函数名:IIC_Receive_Data
功  能:从IIC总线上接收1字节数据
参  数:无
返回值:接收到的数据
******************************************************************************/
unsigned char Simulated_IIC_2_Receive_Data(void)
{
	unsigned char i;
	unsigned char Data;

	Data = 0;

	RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);//主机释放总线,从机在sda发送数据
	//SIMULATED_IIC_2_SDA_DIR = 0; //设置SDA为输入状态
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	for (i = 0; i < 8; i++)
	{
		Data <<= 1;

		RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);////scl拉高,读取从机发送到总线的数据
		//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
		Simulated_IIC_2_Delay();
		Simulated_IIC_2_Delay();
		Simulated_IIC_2_Delay();

		Data |= RTE_GPIO_Get_Level(IIC_SDA_27030);//读取从机数据
		//Data |= SIMULATED_IIC_2_IN_SDA;

		RTE_GPIO_Config(IIC_SCL_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//拉低scl,允许sda变化
		//SIMULATED_IIC_2_SCL_DIR = 1; //SCL输出0,此时SCL = 0
		//SIMULATED_IIC_2_SCL = 0;
		Simulated_IIC_2_Delay();
		Simulated_IIC_2_Delay();
	}

	return Data;
}

/******************************************************************************
函数名:IIC_Transmit_ACK
功  能:向IIC总线上发送确认信号
参  数:ACK:确认信号的类型: SIMULATED_IIC_2_ACK  肯定应答
                              IIC_NAK  否定应答
返回值:无
******************************************************************************/
void Simulated_IIC_2_Transmit_ACK(unsigned char ACK)
{
	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;

	if (ACK > SIMULATED_IIC_2_NAK)
		return;

	if (ACK)
		RTE_GPIO_Config(IIC_SDA_27030,RTE_GPIO_DIR_IN);//用参数来确定是否发送应答信号
		//SIMULATED_IIC_2_SDA_DIR = 0; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
	else
	{
		RTE_GPIO_Config(IIC_SDA_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//用参数来确定是否发送应答信号
		//SIMULATED_IIC_2_SDA_DIR = 1; //SDA输出0,此时SDA = 0
		//SIMULATED_IIC_2_OUT_SDA = 0;
	}
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030,RTE_GPIO_DIR_IN);//scl高电平,为了读取从机应答
	//SIMULATED_IIC_2_SCL_DIR = 0; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
	Simulated_IIC_2_Delay();
	Simulated_IIC_2_Delay();

	RTE_GPIO_Config(IIC_SCL_27030, RTE_GPIO_DIR_OUT|RTE_GPIO_LEVEL_LOW);//拉低scl,允许sda变化
	//SIMULATED_IIC_2_SCL_DIR = 1; //SCL输出0,此时SCL = 0
	//SIMULATED_IIC_2_SCL = 0;
	Simulated_IIC_2_Delay();
}

/******************************************************************************
函数名:IIC_Receive_ACK
功  能:获取从总线上接收到的确认信号
参  数:无
返回值:总线上器件的确认信号类型:Simulated_IIC_ACK        肯定应答
                                  SIMULATED_IIC_2_NAK         否定应答
                                  IIC_INVALID_ACK 无效的应答信号(应答信号还未收到)
******************************************************************************/
unsigned char Simulated_IIC_2_Receive_ACK(void)
{
	unsigned char ACK;

	ACK = u8SimulatedIIC2ReceivedACK;
	u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK;

	return ACK;
}

/******************************************************************************
函数名:IIC_Delay
功  能:延时5us,用于收发过程中的时序控制
        注意:必须调整IIC_5us_DELAY_CALIBRATION参数校准延时时间在5us左右
参  数:ACK:确认信号的类型  0 - ACK  1 - NAK
返回值:无
******************************************************************************/
void Simulated_IIC_2_Delay(void)
{
	unsigned char i;

	for (i = 0; i < SIMULATED_IIC_2_FREQ_CALIBRATION; i++)
		__NOP();
}
/*
unsigned char u8SimulatedIIC2Slave = 0U;
void Simulated_IIC_2_Slave_Service(void)
{
    if (u8SimulatedIIC2Slave == 0U)
    {
        if (stIS31Ctr.u8IS31Refresh >= 1U)
        {
            u8SimulatedIIC2Slave = 1U;
        }
        else if ((stPCF85063Ctr.u8PCF85063Read == 1U) || (stPCF85063Ctr.u8PCF85063Write == 1U))
        {
            u8SimulatedIIC2Slave = 2U;
        }
    }
    if (u8SimulatedIIC2Slave == 1U)
    {
        IS31_Service();
        if (stIS31Ctr.u8IS31Refresh == 0U)
        {
            u8SimulatedIIC2Slave = 0U;
        }
    }
    else if (u8SimulatedIIC2Slave == 2U)
    {
        PCF85063_Service();
        if ((stPCF85063Ctr.u8PCF85063Read == 0U) && (stPCF85063Ctr.u8PCF85063Write == 0U))
        {
            u8SimulatedIIC2Slave = 0U;
        }
    }
}
*/