
/* touch panel interface define */
sbit SDA	   =    P3^0;
sbit SCL       =    P3^1;
sbit PEN_INT       =    P3^2;	
sbit RESET	   =	P3^3;


//Touch Status	 
#define Key_Down 0x01
#define Key_Up   0x00 


struct _ts_event
{
    uint    x1;
    uint    y1;
    uint    x2;
    uint    y2;
    uint    x3;
    uint    y3;
    uint    x4;
    uint    y4;
    uint    x5;
    uint    y5;
	
    uchar     touch_point;
	uchar     Key_Sta;	
};

struct _ts_event ts_event; 

#define WRITE_ADD	0xba 
#define READ_ADD	0xbb

#define CT_MAX_TOUCH    5		//电容触摸屏最大支持的点数

// Registers define
#define GTP_READ_COOR_ADDR    0x814e
#define GTP_REG_SLEEP         0x8040
#define GTP_REG_SENSOR_ID     0x814a
#define GTP_REG_CONFIG_DATA   0x8047
#define GTP_REG_VERSION       0x8440

//#define CT_READ_XY_REG 	0x814E  	//读取坐标寄存器 
//#define CT_CONFIG_REG   0x8047	//配置参数起始寄存器

 uchar code GTP_CFG_DATA[]=
{ 
0x5B,0xD0,0x02,0x00,0x05,0x05,0x35,0x00,0x01,0x0A,
0x28,0x0F,0x5A,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x17,0x18,0x1E,0x13,0x87,0x29,0x0A,
0x32,0x34,0x0C,0x08,0x00,0x00,0x00,0x03,0x02,0x1D,
0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x28,0x55,0x94,0xD5,0x02,0x07,0x00,0x00,0x04,
0x8D,0x2B,0x00,0x80,0x32,0x00,0x75,0x3A,0x00,0x6C,
0x43,0x00,0x64,0x4F,0x00,0x64,0x00,0x00,0x00,0x00,
0xF0,0x4A,0x3A,0xFF,0xFF,0x27,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x14,0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,
0x04,0x02,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x1D,
0x1E,0x1F,0x20,0x21,0x22,0x24,0x26,0x28,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xD9,0x01
};


void TOUCH_Init(void);
void TOUCH_Start(void);
void TOUCH_Stop(void);
uchar   TOUCH_Wait_Ack(void);
void TOUCH_Ack(void);
void TOUCH_NAck(void);

void TOUCH_Send_Byte(uchar txd);
uchar TOUCH_Read_Byte(unsigned char ack);
void Draw_Big_Point(uint x,uint y,uint colour);
uchar GT911_read_data(void);
void inttostr(uint value,uchar *str);


//IIC start
void TOUCH_Start(void)
{ 
	SDA=1;  
	_nop_();
	SCL=1;
	delay_us(3);
	SDA=0;  
	delay_us(3);
	SCL=0;
//	delay_us(1);
}	  


//IIC stop
void TOUCH_Stop(void)
{
	SDA=0;
	_nop_();
	SCL=1;
	delay_us(3);
	SDA=1;
	delay_us(3);
	SCL=0;
//	delay_us(1);						   	
}


//Wait for an answer signal
uchar TOUCH_Wait_Ack(void)
{	uchar errtime=0;

	SDA=1;
//	delay_us(1);
	SCL=1;
//	delay_us(1);
  	while(SDA)
	{
	    errtime++;
	    if(errtime>250)
		    {
		      TOUCH_Stop();
		      return 1;
		    }	
	
	   ;
	}
	SCL=0;
//	delay_us(1);
	return 0;
}



//Acknowledge
void TOUCH_Ack(void)
{	SCL=0;
	_nop_();
	SDA=0;
	delay_us(2);
	SCL=1;
	delay_us(2);
	SCL=0;
	_nop_();
}



//NO Acknowledge		    
void TOUCH_NAck(void)
{	SCL=0;
	delay_us(1);
	SDA=1;
	delay_us(2);
	SCL=1;
	delay_us(2);
	SCL=0;
	_nop_();
}	
	

//IIC send one byte		  
void TOUCH_Send_Byte(uchar Byte)
{	uchar t;  		
 	SCL=0; 
//	delay_us(5);
    for(t=0;t<8;t++)
    {           
	   	SDA=(bit)(Byte & 0x80) ;
	   	Byte <<=1;
		delay_us(2);
	   	SCL=1;
		delay_us(2);
	   	SCL=0;
	//	delay_us(5);
    }	

} 

//Read one byte，ack=0，Send Acknowledge，ack=1，NO Acknowledge   
uchar TOUCH_Read_Byte(uchar ack)
{	uchar t,receive=0;

	SCL=0;
//	delay_us(5);
	SDA=1;
//	delay_us(5);
	for(t = 0; t < 8; t++)
	{	_nop_();
	 	SCL = 0;
		delay_us(4);
	 	SCL=1;
		delay_us(4);
	 	receive<<=1;
	 	if(SDA)receive=receive|0x01;
	//	delay_us(5);
	}

					 
   	if (ack)  TOUCH_NAck();//NO Acknowledge 
   	else       TOUCH_Ack(); //Send Acknowledge   
    
	 return receive;
}

uchar GT911_WR_Reg(uint reg,uchar *buf,uchar len)
{
	uchar i;
	uchar ret=0;
	TOUCH_Start();	
 	TOUCH_Send_Byte(WRITE_ADD);   	//发送写命令 	 
	TOUCH_Wait_Ack();
	TOUCH_Send_Byte(reg>>8);   	//发送高8位地址
	TOUCH_Wait_Ack();	 										  		   
	TOUCH_Send_Byte(reg&0XFF);   	//发送低8位地址
	TOUCH_Wait_Ack(); 
	for(i=0;i<len;i++)
	{	   
    	TOUCH_Send_Byte(buf[i]);  	//发数据
		ret=TOUCH_Wait_Ack();
		if(ret)break;  
	}
    TOUCH_Stop();					//产生一个停止条件	    
	return ret; 
}


void GT911_RD_Reg(uint reg,uchar *buf,uchar len)
{
	uchar i;
 	TOUCH_Start();	
 	TOUCH_Send_Byte(WRITE_ADD);   	//发送写命令 	 
	TOUCH_Wait_Ack(); 
 	TOUCH_Send_Byte(reg>>8);   	//发送高8位地址
	TOUCH_Wait_Ack();  										  		   
 	TOUCH_Send_Byte(reg&0XFF);   	//发送低8位地址
	TOUCH_Wait_Ack();
  
 	TOUCH_Start(); 	 	   
	TOUCH_Send_Byte(READ_ADD);    //发送读命令		   
	TOUCH_Wait_Ack();    
	for(i=0;i<len;i++)
	{	   
    	buf[i]=TOUCH_Read_Byte(i==(len-1)?1:0); //发数据
		
		
	//	if(i==(len-1))  buf[i]=TOUCH_Read_Byte(1);
	//	else            buf[i]=TOUCH_Read_Byte(0);	 
		
	} 
     TOUCH_Stop();//产生一个停止条件	    
}

uchar GT911_Send_Cfg(uchar * buf,uint cfg_len)
{
	uchar ret=0;
	uchar retry=0;
	for(retry=0;retry<5;retry++)
	{
		ret=GT911_WR_Reg(GTP_REG_CONFIG_DATA,buf,cfg_len);
		if(ret==0)break;
		delay_ms(10);	 
	}
	return ret;
}



uchar GT911_read_data(void)
{	uchar buf[50] = {0xff}; uchar ret = 0;	uchar ss[4];


	GT911_RD_Reg(GTP_READ_COOR_ADDR,buf,50);		

	ss[0]=0;		
 	GT911_WR_Reg(GTP_READ_COOR_ADDR,ss,1);	  //Must clear  Buffer status
 
  	ts_event.touch_point = buf[0] & 0x0f;


  /*		FontWrite_Position(20,60);
		String("touch_point=");


 		inttostr(ts_event.touch_point ,ss);
		  LCD_CmdWrite(0x02);
		LCD_DataWrite(ss[0]);	delay_us(2);	
		LCD_DataWrite(ss[1]);	delay_us(2);
		LCD_DataWrite(ss[2]);	delay_us(2);
		LCD_DataWrite(ss[3]);	delay_us(2);	 */

  	if (ts_event.touch_point == 0) 
		{  			

			return 0;
  		}		
   

					switch (ts_event.touch_point) 
					{
 						
							case 5:
				           			ts_event.x5 = (uint)(buf[35] )<<8 | (uint)buf[34];
				           			ts_event.y5 = (uint)(buf[37] )<<8 | (uint)buf[36];
				
						    case 4:
						           	ts_event.x4 = (uint)(buf[27] )<<8 | (uint)buf[26];
						           	ts_event.y4 = (uint)(buf[29] )<<8 | (uint)buf[28];
						
						    case 3:
						           	ts_event.x3 = (uint)(buf[19] )<<8 | (uint)buf[18];
						           	ts_event.y3 = (uint)(buf[21] )<<8 | (uint)buf[20];
						
						    case 2:
						           	ts_event.x2 = (uint)(buf[11] )<<8 | (uint)buf[10];
						           	ts_event.y2 = (uint)(buf[13] )<<8 | (uint)buf[12];
						
						    case 1:
						           	ts_event.x1 = (uint)(buf[3] )<<8 | (uint)buf[2];
						           	ts_event.y1 = (uint)(buf[5] )<<8 | (uint)buf[4];
				
				    break;
						    default:
						    return 0;
					}


	   
	return ret;
}


void inttostr(uint value,uchar *str)
{
	str[0]=value/1000+48;
	str[1]=value%1000/100+48;
	str[2]=value%1000%100/10+48;
 	str[3]=value%1000%100%10+48;
}



void TOUCH_Init(void)
{	
	/*	RESET=0;
		PEN_INT=0;
		Delay1ms(30);
 		PEN_INT=1;
		Delay1ms(5);
		RESET=1;;
		Delay1ms(20);
		ACC=PEN_INT;
		ACC=PEN_INT;
 		Delay1ms(200);	 */

 		RESET=0;						   
		PEN_INT=0;
		delay_ms(20);
 		RESET=1;
		delay_ms(500);
		ACC=PEN_INT;
 		ACC=PEN_INT;
 		delay_ms(200);

		ts_event.x1=0;
		ts_event.y1=0;
		ts_event.x2=0;
		ts_event.y2=0;
		ts_event.x3=0;
		ts_event.y3=0;
		ts_event.x4=0;
		ts_event.y4=0;
		ts_event.x5=0;
		ts_event.y5=0;
    	ts_event.Key_Sta=Key_Up;
	   
}	

void LCD_DrawCircle_Fill
(
 unsigned short XCenter         
,unsigned short YCenter           
,unsigned short R                
,unsigned long ForegroundColor 
)
{
	Foreground_color_65k(ForegroundColor);
	Circle_Center_XY(XCenter,YCenter);
  Circle_Radius_R(R);
  Start_Circle_or_Ellipse_Fill();
  Check_2D_Busy(); 
}


void TPTEST(void)
{uchar ss[4]; uchar re=0; uchar bb[187]; uchar i;
  
   Select_Main_Window_16bpp();
	Main_Image_Start_Address(0);				
	Main_Image_Width(LCD_XSIZE_TFT);							
	Main_Window_Start_XY(0,0);

	Canvas_Image_Start_address(0);//Layer 1
	Canvas_image_width(LCD_XSIZE_TFT);//
    Active_Window_XY(0,0);
	Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT);

 	Foreground_color_65k(Black);
	Line_Start_XY(0,0);
	Line_End_XY(LCD_XSIZE_TFT,LCD_YSIZE_TFT);
	Start_Square_Fill();
 	 delay_ms(100);
 ///////////////////////////Square
	Foreground_color_65k(Red);
	Line_Start_XY(0,0);
	Line_End_XY(LCD_XSIZE_TFT-1,LCD_YSIZE_TFT-1);
	Start_Square();
 	 delay_ms(100);

	Foreground_color_65k(Red);
	Background_color_65k(Black);
	CGROM_Select_Internal_CGROM();
	Font_Select_8x16_16x16();

	TOUCH_Init();

	GT911_Send_Cfg((uchar*)GTP_CFG_DATA,sizeof(GTP_CFG_DATA));

	GT911_RD_Reg(GTP_REG_CONFIG_DATA,ss,sizeof(GTP_CFG_DATA));
	if((ss[1]==0xd0)&&(ss[2]==0x02	))
	{Goto_Text_XY(2,2);Show_String("send CFG OK");}
	 else  {Goto_Text_XY(2,2);Show_String("send CFG NOK");}

  

 	   
/*	 	GT911_RD_Reg(GTP_REG_CONFIG_DATA,bb,sizeof(GTP_CFG_DATA));

		  
		i=0;
		  Text_Mode();
		 Goto_Text_XY(0,100);
	 while(i<186)				
		{	inttostr(bb[i],ss);
		 LCD_CmdWrite(0x04);
		LCD_DataWrite(ss[0]);	delay_us(2); Check_Mem_WR_FIFO_not_Full();	
		LCD_DataWrite(ss[1]);	delay_us(2); Check_Mem_WR_FIFO_not_Full();
		LCD_DataWrite(ss[2]);	delay_us(2);  Check_Mem_WR_FIFO_not_Full();
		LCD_DataWrite(ss[3]);	delay_us(2);  Check_Mem_WR_FIFO_not_Full();
		LCD_DataWrite(',');	delay_us(2);   Check_Mem_WR_FIFO_not_Full();
		i+=1;
		}
	  */


	Foreground_color_65k(White);
	Background_color_65k(Black);

		Font_Select_8x16_16x16();
		Goto_Text_XY(40,200);	
		Show_String("Capacitive touch screen test");
		Goto_Text_XY(LCD_XSIZE_TFT-48,LCD_YSIZE_TFT-20);
		Show_String("Clear");   
		Goto_Text_XY(15,LCD_YSIZE_TFT-20);
		Show_String("Exit");

 	while(next)
	{
	    	GT911_RD_Reg(GTP_READ_COOR_ADDR,ss,1);
	    	  if(ss[0]&0x80==0x80);	
//	 if(ts_event.Key_Sta==Key_Down)        //The touch screen is pressed
			{
					GT911_read_data();
					ts_event.Key_Sta=Key_Up;
				
				if ((ts_event.x1<85) &&(ts_event.y1>1240))return;// flag=0; 
            	if ((ts_event.x1>630) &&(ts_event.y1>1240))
              	{ 
				  	Foreground_color_65k(Black);
					Line_Start_XY(0,0);
					Line_End_XY(LCD_XSIZE_TFT,LCD_YSIZE_TFT);
					Start_Square_Fill();
					  	 
				 	Foreground_color_65k(Red);
					Line_Start_XY(0,0);
					Line_End_XY(LCD_XSIZE_TFT-1,LCD_YSIZE_TFT-1);
					Start_Square();
					 	
					Foreground_color_65k(White);
					Background_color_65k(Black);
					CGROM_Select_Internal_CGROM();
					Font_Select_8x16_16x16();
					Goto_Text_XY(40,200);
					Show_String("Capacitive touch screen test");
					Goto_Text_XY(LCD_XSIZE_TFT-48,LCD_YSIZE_TFT-20);
					Show_String("Clear");   
					Goto_Text_XY(15,LCD_YSIZE_TFT-20);
					Show_String("Exit");

					ts_event.x1=0 ; ts_event.y1=0;
              	} 

						
         
		
					inttostr(ts_event.x1,ss);	

					Foreground_color_65k(White);
					Background_color_65k(Black);
					CGROM_Select_Internal_CGROM();
					Font_Select_8x16_16x16();
					Goto_Text_XY(100,60);
					Show_String("X = ");	

					Text_Mode();
					LCD_CmdWrite(0x04);							
				  	LCD_DataWrite(ss[0]);
					//Delay1ms(1);
				  	LCD_DataWrite(ss[1]);
					//Delay1ms(1);
				  	LCD_DataWrite(ss[2]);
					//Delay1ms(1);
 				  	LCD_DataWrite(ss[3]);	 

					inttostr(ts_event.y1,ss);
					Goto_Text_XY(100,140);   //Set the display position
				  	LCD_CmdWrite(0x02);
					Show_String("Y = ");	
					Text_Mode();
					LCD_CmdWrite(0x04);	
				  	LCD_DataWrite(ss[0]);
					//Delay1ms(1);
				  	LCD_DataWrite(ss[1]);
					//Delay1ms(1);
				  	LCD_DataWrite(ss[2]);
					//Delay1ms(1);
 				  	LCD_DataWrite(ss[3]);


					if(ts_event.touch_point == 1)	{LCD_DrawCircle_Fill(ts_event.x1,ts_event.y1,2,Red);}

					if(ts_event.touch_point == 2)	{LCD_DrawCircle_Fill(ts_event.x1,ts_event.y1,2,Red);
													 LCD_DrawCircle_Fill(ts_event.x2,ts_event.y2,2,Green);}
													 	
					if(ts_event.touch_point == 3)	{LCD_DrawCircle_Fill(ts_event.x1,ts_event.y1,2,Red);
													 LCD_DrawCircle_Fill(ts_event.x2,ts_event.y2,2,Green);
													 LCD_DrawCircle_Fill(ts_event.x3,ts_event.y3,2,Blue);}

					if(ts_event.touch_point == 4)	{LCD_DrawCircle_Fill(ts_event.x1,ts_event.y1,2,Red);
													 LCD_DrawCircle_Fill(ts_event.x2,ts_event.y2,2,Green);
													 LCD_DrawCircle_Fill(ts_event.x3,ts_event.y3,2,Blue);
													 LCD_DrawCircle_Fill(ts_event.x4,ts_event.y4,2,Cyan);}	

					if(ts_event.touch_point == 5)	{LCD_DrawCircle_Fill(ts_event.x1,ts_event.y1,2,Red);
													 LCD_DrawCircle_Fill(ts_event.x2,ts_event.y2,2,Green);
													 LCD_DrawCircle_Fill(ts_event.x3,ts_event.y3,2,Blue);
													 LCD_DrawCircle_Fill(ts_event.x4,ts_event.y4,2,Cyan);
													 LCD_DrawCircle_Fill(ts_event.x5,ts_event.y5,2,Magenta);}

			
			}	

	

    }
   	
  
      
}


				