#include "i2c.h"



/*************配置SDA引脚为输出********************/
void SCL_OUTPUT(void)
{
	GPIO_InitTypeDef I2CGPIOInitStruct;
//    GPIO_PinStateTypeDef PinState;

    I2CGPIOInitStruct.Pin = I2C_PIN_SCL;
    I2CGPIOInitStruct.Dir = GPIO_DIR_OUT;
    I2CGPIOInitStruct.OutputMode = GPIO_OUTPUT_MODE_CMOS;
    I2CGPIOInitStruct.PullMode = GPIO_PULL_MODE_UP;
    HAL_I2C_GPIOInit(I2C1, &I2CGPIOInitStruct);
}

/*************配置SDA引脚为输出********************/
void SDA_OUTPUT(void)
{
	 GPIO_InitTypeDef I2CGPIOInitStruct;
//    GPIO_PinStateTypeDef PinState;

    I2CGPIOInitStruct.Pin = I2C_PIN_SDA;
    I2CGPIOInitStruct.Dir = GPIO_DIR_OUT;
    I2CGPIOInitStruct.OutputMode = GPIO_OUTPUT_MODE_CMOS;
    I2CGPIOInitStruct.PullMode = GPIO_PULL_MODE_UP;
    HAL_I2C_GPIOInit(I2C1, &I2CGPIOInitStruct);
}

/**************配置SDA引脚为输入*****************/
void SDA_INPUT(void)
{
	GPIO_InitTypeDef I2CGPIOInitStruct;
//    GPIO_PinStateTypeDef PinState;
		
    I2CGPIOInitStruct.Pin = I2C_PIN_SDA;
    I2CGPIOInitStruct.Dir = GPIO_DIR_IN;
    I2CGPIOInitStruct.OutputMode = GPIO_OUTPUT_MODE_CMOS;
    I2CGPIOInitStruct.PullMode = GPIO_PULL_MODE_UP;
    HAL_I2C_GPIOInit(I2C1, &I2CGPIOInitStruct);
}

void CT_DELAY_US(UINT32 val)
{
	volatile u32 time=200;
	while(time--);
}

/*****************************CTI2C启动函数***************************/
static void CTI2C_start(void)
{
	SDA_OUTPUT();
	SDA_High;
	CT_DELAY_US(1);
	SCL_High;
	CT_DELAY_US(1);
	SDA_Low;
	CT_DELAY_US(1);
	SCL_Low;
	CT_DELAY_US(1);
}

/*****************************CTI2C停止函数**************************/
static void CTI2C_stop(void)
{
	SDA_OUTPUT();
	SCL_Low;
	CT_DELAY_US(1);
	SDA_Low;

	CT_DELAY_US(1);
	SCL_High;
	CT_DELAY_US(1);
	SDA_High;
	CT_DELAY_US(1);
}

/********************CTI2C写1byte函数,S为需要写的内容*****************/
u8 CTI2C_write_byte(u8 s)
{
	u8 ch_data,iii=0;

	SDA_OUTPUT();			
	ch_data=s;
	SCL_Low;
	for(iii=0;iii<8;iii++)
	{
		if(ch_data&0x80)
						SDA_High;
		else    SDA_Low;
		CT_DELAY_US(1);
		SCL_High;
		CT_DELAY_US(1);
		SCL_Low;                       
		ch_data=ch_data<<1;
	}
	//Read ACK
	SDA_INPUT();			
	SDA_High;
	CT_DELAY_US(1);
	SCL_High;
	CT_DELAY_US(1);
	if(GetSDABit==0)
	{
		SCL_Low;
		return 0;
	}
	else
	{
		SCL_Low;
		return 1;
	}
}

///****************CTI2C读1byte函数，返回值为所读数据*****************/
u8 CTI2C_read_byte(uint8_t ack)
{
	u8 ch_data,iii=0;

	SDA_INPUT();
	ch_data=0x00;               
	for(iii=0;iii<8;iii++)
	{
		ch_data=ch_data<<1;
		SCL_Low;             
		SDA_High;		
		CT_DELAY_US(1);
		SCL_High;
		CT_DELAY_US(1);
		if(GetSDABit==1)  ch_data=ch_data|0x01;
	}
	SCL_Low;
	SDA_OUTPUT();
	SCL_Low;
	if(!ack)
	{
		SDA_Low;		
		CT_DELAY_US(1);
		SCL_High;
		CT_DELAY_US(1);
		SCL_Low;
	}
	else
	{
		SDA_High;		
		CT_DELAY_US(1);
		SCL_High;
		CT_DELAY_US(1);
		SCL_Low;
	}

	return ch_data;
}

/******************************************************************************
 * FUNCTION: CT_Read_Nbyte ( )
 * DESCRIPTION: 从触摸屏中读出数据
 *    Input the description of function:
 * Input Parameters: 器件地址，待读寄存器地址，待读数据数量，存储待读出数据的地址
 * Output Parameters: 读取的数据
 * Returns Value:
 ******************************************************************************/
u8 CT_Read_Nbyte(uint8_t sla_add,uint16_t len_addr,uint16_t add,uint16_t n,uint8_t *s)					//CTI2C读nbyte函数,所读数据放在形参数组中（由程序员设置合适的数组大小），成功返回1，失败返回0
{
	u8 temps;
	u16 tempn;
	CTI2C_start();																																				//启动CTI2C总线
	CTI2C_write_byte(sla_add | CT_WRITE_MASK);
	
//#if GT_TOUCH
//	CTI2C_write_byte(add>>8);
//#endif
	if(len_addr>1)	CTI2C_write_byte(add>>8);
	
	CTI2C_write_byte(add);
	CTI2C_stop();
	CTI2C_start();																																				//再次启动CTI2C总线
	CTI2C_write_byte(sla_add | CT_READ_MASK);
	for(tempn=0;tempn<n;tempn++)
	{

		if(tempn+1<n)																																				//如果已经读完所有数据了，就不要发应答信号，直接发非应答位和停止位
		{
			temps = CTI2C_read_byte(0);
			*(s+tempn)=temps;
		}
	}
	temps = CTI2C_read_byte(1);
	*(s+tempn-1)=temps;
	CTI2C_stop();

	return 0;
}

/******************************************************************************
 * FUNTPION: TP_Write_Nbyte ( )
 * DESCRIPTION: 写触摸屏寄存器
 *    Input the description of funTPion: 
 * Input Parameters: 器件地址，待写寄存器地址，待写数据数量，存储待写入数据的地址
 * Output Parameters: 无
 * Returns Value: 
 ******************************************************************************/
uint8_t CT_Write_Nbyte(uint8_t sla_add,uint16_t len_addr,uint16_t add,uint16_t n,uint8_t *s)//TP写nbyte函数，写数据由形参数组传入，成功返回1，失败返回0
{
    //uint8_t temps,ack=1;
    uint16_t tempn;
    //uint16_t cack_time=0;
    CTI2C_start();//启动TP总线
    CTI2C_write_byte(sla_add | CT_WRITE_MASK);//发送寻址字节

//#if GT_TOUCH
//	CTI2C_write_byte(add>>8);
//#endif	
	if(len_addr>1)	CTI2C_write_byte(add>>8);
	
    CTI2C_write_byte(add);//发送要写入的起始地址
	
	for(tempn=0;tempn<n;tempn++) CTI2C_write_byte(s[tempn]);
 
 /*
    for(tempn=0;tempn<n;tempn++)
    {
        ack=1;//应答位
        cack_time=0;
        temps=*(s+tempn);
        while(ack)
        {
           ack= CTI2C_write_byte(temps);
            cack_time++;
            if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号，返回出错信号
                return CT_ACK_FAIL;
        }
    }*/
    CTI2C_stop();// TP停止
    return 0;
}
