#include "ott2001a.h"
#include "touch.h"
#include "ctiic.h"
#include "usart.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用，未经作者许可，不得用于其它任何用途
//ALIENTEK STM32F407开发板
//4.3寸电容触摸屏-OTT2001A 驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/7
//版本：V1.0
//版权所有，盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved									  
////////////////////////////////////////////////////////////////////////////////// 

//向OTT2001A写入一次数据
//reg:起始寄存器地址
//buf:数据缓冲区
//len:写数据长度
//返回值:0,成功;1,失败
u8 OTT2001A_WR_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i;
	u8 ret=0;
	CT_IIC_Start();	
 	CT_IIC_Send_Byte(OTT_CMD_WR);   //发送写命令 	 
	CT_IIC_Wait_Ack();
	CT_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	CT_IIC_Wait_Ack(); 	 										  		   
	CT_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	CT_IIC_Wait_Ack();  
	for(i=0;i<len;i++)
	{	   
    	CT_IIC_Send_Byte(buf[i]);  	//发数据
		ret=CT_IIC_Wait_Ack();
		if(ret)break;  
	}
    CT_IIC_Stop();					//产生一个停止条件	    
	return ret; 
}

//从OTT2001A读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度
void OTT2001A_RD_Reg(u16 reg,u8 *buf,u8 len)
{
	u8 i; 
 	CT_IIC_Start();	
 	CT_IIC_Send_Byte(OTT_CMD_WR);   //发送写命令 	 
	CT_IIC_Wait_Ack();
 	CT_IIC_Send_Byte(reg>>8);   	//发送高8位地址
	CT_IIC_Wait_Ack(); 	 										  		   
 	CT_IIC_Send_Byte(reg&0XFF);   	//发送低8位地址
	CT_IIC_Wait_Ack();  
 	CT_IIC_Start();  	 	   
	CT_IIC_Send_Byte(OTT_CMD_RD);   //发送读命令		   
	CT_IIC_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
    	buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据	  
	} 
  CT_IIC_Stop();//产生一个停止条件    
}

//传感器打开/关闭操作
//cmd:1,打开传感器;0,关闭传感器
void OTT2001A_SensorControl(u8 cmd)
{
	u8 regval=0X00;
	if(cmd)regval=0X80;
	OTT2001A_WR_Reg(OTT_CTRL_REG,&regval,1); 
} 

//初始化触摸屏
//返回值:0,初始化成功;1,初始化失败
u8 OTT2001A_Init(void)
{
	u8 regval = 0;
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC,ENABLE); //开启GPIOB与GPIOC时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PB1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB1
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PC13
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
	GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PC13
	
	CT_IIC_Init();  //初始化电容屏的I2C总线
	OTT_RST = 0;//复位
	delay_ms(100);
	OTT_RST = 1; //释放复位
	delay_ms(100);
	OTT2001A_SensorControl(1);  //打开传感器
	OTT2001A_RD_Reg(OTT_CTRL_REG,&regval,1);//读取传感器运行寄存器的值来判断I2C通信是否正常
	printf("CTP ID:%x\r\n",regval);
		if(regval == 0X80)return 0;
	return 1;
}

const u16 OTT_TPX_TBL[5]={OTT_TP1_REG,OTT_TP2_REG,OTT_TP3_REG,OTT_TP4_REG,OTT_TP5_REG};
//扫描触摸屏(采用查询方式)
//mode:0,正常扫描.
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 OTT2001A_Scan(u8 mode)
{
	u8 buf[4];
	u8 i=0;
	u8 res=0;
	static u8 t=0; //控制查询间隔,从而降低cpu占用率
	t++;
	if((t%10)==0 || t<10) //空闲时,每进入10次CTP_Scan函数才检测一次,从而节省CPU使用率
	{
		OTT2001A_RD_Reg(OTT_GSTID_REG,&mode,1);//读取触摸点的状态 
		if(mode&0x1F)  //当有触摸点按下时
		{	
			tp_dev.sta = (mode&0x1F)|TP_PRES_DOWN|TP_CATH_PRES;
			for(i=0;i<5;i++) //获取触摸值
			{
				if(tp_dev.sta&(1<<i)) //触摸有效？
				{
					OTT2001A_RD_Reg(OTT_TPX_TBL[i],buf,4);//读取触摸值
					if(tp_dev.touchtype&0x01) //横屏
					{
						tp_dev.y[i] = (((u16)buf[2]<<8)+buf[3])*OTT_SCAL_Y;
						tp_dev.x[i] = 800-(((u16)buf[0]<<8)+buf[1])*OTT_SCAL_X;
					}else
					{
						tp_dev.x[i] = (((u16)buf[2]<<8)+buf[3])*OTT_SCAL_Y;
						tp_dev.y[i] = (((u16)buf[0]<<8)+buf[1])*OTT_SCAL_X;
					}
				}
			}
			res =1;
			if(tp_dev.x[0]==0 && tp_dev.y[0]==0)mode=0;//读到的数据都是0,则忽略此次数据
			t = 0;//触发一次,则会最少连续监测10次,从而提高命中率
		}
	}
	if((mode&0X1F) == 0) //无触摸点按下
	{
		if(tp_dev.sta & TP_PRES_DOWN) //之前是被按下的
		{
			tp_dev.sta &= ~(1<<7); //标记按键松开
		}else //之前就没有按下
		{
			tp_dev.x[0] = 0Xffff;
			tp_dev.y[0] = 0Xffff;
			tp_dev.sta &= 0XE0; //清除点有效标记
		}
	}
	if(t>240)t=10;//重新从10开始计数
	return res;
}

