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

#include "LtDet_Simulated_IIC_Master.h"
#include "gpio.h"

uint8_t LtDet_IICReceivedACK;

/******************************************************************************
函数名：IIC_Init
功  能：初始化IIC总线
参  数：无
返回值：无
******************************************************************************/
void LtDet_IIC_Init(void)
{
//  PORT_Init(IIC_SCL_LtDet, OPENDRAIN_OUTPUT);   //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();
  
  //PORT_Init(IIC_SDA_LtDet, INPUT);   //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay(); 
  
  LtDet_IICReceivedACK = IIC_INVALID_ACK;
}

/******************************************************************************
函数名：IIC_Start
功  能：在IIC总线上发送起始信号,发起一次IIC通信
参  数：无
返回值：无
******************************************************************************/
void LtDet_IIC_Start(void)
{
  LtDet_IICReceivedACK = IIC_INVALID_ACK;
//  PORT_SetBit(IIC_SDA_LtDet);   //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();
   
//  PORT_SetBit(IIC_SCL_LtDet);   //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();

//  PORT_Init(IIC_SDA_LtDet, OPENDRAIN_OUTPUT);   //SDA输出0,此时SDA = 0
//  PORT_ClrBit(IIC_SDA_LtDet);
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();

//  PORT_ClrBit(IIC_SCL_LtDet); //SCL输出0,此时SCL = 0
  LtDet_IIC_Delay();
}

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

//  PORT_Init(IIC_SDA_LtDet, OPENDRAIN_OUTPUT);   //SDA输出0,此时SDA = 0
//  PORT_ClrBit(IIC_SDA_LtDet);
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();
  
//  PORT_SetBit(IIC_SCL_LtDet);   //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();
  
//  PORT_SetBit(IIC_SDA_LtDet);   //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay(); 
}

/******************************************************************************
函数名：IIC_Transmit_Data
功  能：向IIC总线上发送1字节数据
参  数：Data：发送的数据
返回值：总线上器件的确认(ACK)  0 - ACK  1 - NAK
******************************************************************************/
void LtDet_IIC_Transmit_Data(uint8_t Data)
{
  uint8_t i;
	
	LtDet_IICReceivedACK = IIC_INVALID_ACK;
	 
     
	for (i = 0; i < 8; i++)
	{
//    PORT_ClrBit(IIC_SCL_LtDet);
     LtDet_IIC_Delay();	
    if (Data & 0x80){
//        PORT_Init(IIC_SDA_LtDet, OPENDRAIN_OUTPUT);
//        PORT_SetBit(IIC_SDA_LtDet);
  //    IIC_SDA_DIR = 0;   //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
			;
		}	
    else
    {
//      PORT_Init(IIC_SDA_LtDet, OPENDRAIN_OUTPUT);
//      PORT_ClrBit(IIC_SDA_LtDet);
    //  IIC_SDA_DIR = 1;   //SDA输出0,此时SDA = 0
   //   IIC_SDA = 0; 
    }
    LtDet_IIC_Delay();
    LtDet_IIC_Delay();

//    PORT_SetBit(IIC_SCL_LtDet);
   // IIC_SCL_DIR = 0;     //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
    LtDet_IIC_Delay();
    LtDet_IIC_Delay();

   
   // IIC_SCL_DIR = 1;     //SCL输出0,此时SCL = 0
   // IIC_SCL = 0;
    
	
    Data <<= 1;
	}
//    PORT_ClrBit(IIC_SCL_LtDet);
//    PORT_Init(IIC_SDA_LtDet, INPUT);
  

  LtDet_IIC_Delay();
  LtDet_IIC_Delay();

//  PORT_SetBit(IIC_SCL_LtDet);
//  IIC_SCL_DIR = 0;       //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();
//  if(PORT_GetBit(IIC_SDA_LtDet)){
//    LtDet_IICReceivedACK = 1;
//  }
//  else{
//    LtDet_IICReceivedACK = 0;
 // }
  
  
//	IICReceivedACK = IIC_SDA;

//  PORT_ClrBit(IIC_SCL_LtDet);
 // IIC_SCL_DIR = 1;       //SCL输出0,此时SCL = 0
 // IIC_SCL = 0;
  LtDet_IIC_Delay();
}

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

  Data = 0;

//  PORT_Init(IIC_SDA_LtDet, INPUT);
  //IIC_SDA_DIR = 0;       //设置SDA为输入状态
  LtDet_IIC_Delay();
  LtDet_IIC_Delay();

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

//      PORT_SetBit(IIC_SCL_LtDet);
 	//  IIC_SCL_DIR = 0;     //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
      LtDet_IIC_Delay();
      LtDet_IIC_Delay();
      LtDet_IIC_Delay();
//      if(PORT_GetBit(IIC_SDA_LtDet))
//          Data |= 1;

//      PORT_ClrBit(IIC_SCL_LtDet);
    //  IIC_SCL_DIR = 1;     //SCL输出0,此时SCL = 0
    //  IIC_SCL = 0;
      LtDet_IIC_Delay();
      LtDet_IIC_Delay();
 	}
 	
	return Data;
}

/******************************************************************************
函数名：IIC_Transmit_ACK
功  能：向IIC总线上发送确认信号
参  数：ACK：确认信号的类型： IIC_ACK  肯定应答
                              IIC_NAK  否定应答
返回值：无
******************************************************************************/
void LtDet_IIC_Transmit_ACK(uint8_t ACK)
{
  LtDet_IICReceivedACK = IIC_INVALID_ACK;

  if (ACK > IIC_NAK)
    return;
//  PORT_Init(IIC_SDA_LtDet, OPENDRAIN_OUTPUT);
//  if(ACK)
//    PORT_SetBit(IIC_SDA_LtDet);
   // IIC_SDA_DIR = 0;     //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1
// 	else
 //	{
// 	    PORT_ClrBit(IIC_SDA_LtDet);
//    IIC_SDA_DIR = 1;     //SDA输出0,此时SDA = 0
  //  IIC_SDA = 0;
//	}
//  LtDet_IIC_Delay();

//  PORT_SetBit(IIC_SCL_LtDet);
 // IIC_SCL_DIR = 0;       //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1
//  LtDet_IIC_Delay();
//  LtDet_IIC_Delay();
//
//  PORT_ClrBit(IIC_SCL_LtDet);
// // IIC_SCL_DIR = 1;       //SCL输出0,此时SCL = 0
// // IIC_SCL = 0;
//  LtDet_IIC_Delay();
}

/******************************************************************************
函数名：IIC_Receive_ACK
功  能：获取从总线上接收到的确认信号
参  数：无
返回值：总线上器件的确认信号类型：IIC_ACK         肯定应答
                                  IIC_NAK         否定应答
                                  IIC_INVALID_ACK 无效的应答信号(应答信号还未收到)
******************************************************************************/
uint8_t LtDet_IIC_Receive_ACK(void)
{
  uint8_t ACK;
  
  ACK = LtDet_IICReceivedACK;
  LtDet_IICReceivedACK = IIC_INVALID_ACK;
  
  return ACK;
}

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