/* touch panel interface define */
//sbit SDA	   =    P3^0;  //Data
//sbit SCL       =    P3^1; //Clock
sbit PEN       =    P3^2;  //TP interrrupt    GSL1680 is high levels interrrupt   MCU is low levels interrrupt  So here need to connect an inverter	
sbit WAKE	   =	P3^3;  //Wake signal  low:wake

sbit led	   =	P3^7;  //Touch Flag

#include"gslX680.h"


//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	0x80  
#define READ_ADD	0x81  

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 TOUCH_Wr_Reg(uchar RegIndex,uchar RegValue1);
void TOUCH_RdParFrPCTPFun(uchar *PCTP_Par,uchar ValFlag);
uchar   TOUCH_Read_Reg(uchar RegIndex);
void Draw_Big_Point(uint x,uint y,uint colour);
uchar GSLX680_read_data(void);



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


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

/*
//Wait for an answer signal
uchar TOUCH_Wait_Ack(void)
{
    unsigned char ack=1;
	SDA=1;
    SCL=1;
	delayus(2);
    while(ack==1){ack=SDA;}
	delayus(2);
    SCL=0;
    return 0;

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

	SDA=1;
	delayus(1);
	SCL=1;
//	delayus(1);
  	while(SDA)
	{
	    errtime++;
	    if(errtime>100)
		    {
		      TOUCH_Stop();
		      return 1;
		    }
	}
	SCL=0;
	_nop_();
}



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



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

//IIC send one byte	
void TOUCH_Send_Byte(uchar Byte)
{	uchar t;  		

    for(t=7; (t>=0)&&(t<=7); t--)
    { 	SCL=0;            
        if((Byte>>t)&0x01)
        SDA=1;
        else
        SDA=0;
		delayus(2);
	   	SCL=1;
		delayus(2);
	   	SCL=0;
		delayus(2);
    }	
 

} 




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

	SCL=0;
	SDA=1;
	for(t = 0; t < 8; t++)
	{	_nop_();
	 	SCL = 1;
		_nop_();
	 	receive<<=1;
	 	if(SDA == 1)
	 	receive=receive|0x01;
		delayus(2);
	 	SCL=0;
		delayus(2);
	}

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



//GSLX680_I2C_Write
static void GSLX680_I2C_Write(uchar *reg, uchar *addr, ulong cnt)
{
	uint i=0;

	
	TOUCH_Start();
	TOUCH_Send_Byte(WRITE_ADD);
	TOUCH_Wait_Ack();	
	TOUCH_Send_Byte(*reg);
	TOUCH_Wait_Ack();

	for(i=0;i<cnt;i++,addr++)//data
	{		
		TOUCH_Send_Byte(*addr);
		TOUCH_Wait_Ack();
	}
	TOUCH_Stop();
}

//GSLX680_I2C_Read
static void GSLX680_I2C_Read(uchar *reg, uchar *addr, ulong cnt)
{
       uint num=0;

	TOUCH_Start();
	TOUCH_Send_Byte(WRITE_ADD);
	TOUCH_Wait_Ack();	
	TOUCH_Send_Byte(*reg);
	TOUCH_Wait_Ack();
	TOUCH_Stop();

	TOUCH_Start();	
	TOUCH_Send_Byte(READ_ADD);//chip adress
	TOUCH_Wait_Ack();	
	
	for(num=0;num<cnt;num++)
  	{
		if(num==(cnt-1))  
		addr[num]=TOUCH_Read_Byte(1);   
        else 
    	addr[num]=TOUCH_Read_Byte(0);   
  	}	
	
	TOUCH_Stop();


}


//get the most data about capacitive touchpanel.
uchar GSLX680_read_data(void)
{	uchar touch_data[24] = {0}; 
	uchar reg = 0x80;
	GSLX680_I2C_Read(&reg, touch_data, 24);





				
				           			ts_event.y5 = (uint)(touch_data[23])<<8 | (uint)touch_data[22];
				           			ts_event.x5 = (uint)(touch_data[21])<<8 | (uint)touch_data[20];
				
						   
						           	ts_event.y4 = (uint)(touch_data[19])<<8 | (uint)touch_data[18];
						           	ts_event.x4 = (uint)(touch_data[17])<<8 | (uint)touch_data[16];
						
						
						           	ts_event.y3 = (uint)(touch_data[15])<<8 | (uint)touch_data[14];
						           	ts_event.x3 = (uint)(touch_data[13])<<8 | (uint)touch_data[12];
						
						  
						           	ts_event.y2 = (uint)(touch_data[11])<<8 | (uint)touch_data[10];
						           	ts_event.x2 = (uint)(touch_data[9])<<8 | (uint)touch_data[8];
						
						 
						           	ts_event.y1 = (uint)(touch_data[7])<<8 | (uint)touch_data[6];
						           	ts_event.x1 = (uint)(touch_data[5])<<8 | (uint)touch_data[4];
				
	

	return 0;	
}




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

}




//TP interrrupt    GSL1680 is high levels interrrupt   MCU is low levels interrrupt     So here need to connect an inverter
////////////////////////////////////
void  counter0(void) interrupt 0
{
 	if(PEN==0)										//Detect the occurrence of an interrupt
 	{
		ts_event.Key_Sta=Key_Down;                              
		led=~led;
 	}
}


//GSLX680 Clear reg
static void _GSLX680_clr_reg(void)
{
	uchar addr;	
	uchar Wrbuf[4];

	addr = 0xe0;
	Wrbuf[0] = 0x88;
	GSLX680_I2C_Write(0xe0, Wrbuf, 1); 	
	delayus(200);
	addr = 0x80;
	Wrbuf[0] = 0x01;
	GSLX680_I2C_Write(&addr, Wrbuf, 1); 	
	delayus(50);
	addr = 0xe4;
	Wrbuf[0] = 0x04;
	GSLX680_I2C_Write(&addr, Wrbuf, 1); 	
	delayus(50);
	addr = 0xe0;
	Wrbuf[0] = 0x00;
	GSLX680_I2C_Write(&addr, Wrbuf, 1); 	
	delayus(50);
}
//_GSLX680 Reset
static void _GSLX680_reset_chip(void)
{
	uchar addr;	
	uchar Wrbuf[4];
	

	addr = 0xe0;
	Wrbuf[0] = 0x88;
       GSLX680_I2C_Write(&addr,Wrbuf, 1);
	delayus(50);

	addr = 0xe4;
	Wrbuf[0] = 0x04;
       GSLX680_I2C_Write(&addr,Wrbuf, 1);
	delayus(50);

	addr = 0xbc;
	Wrbuf[0] = 0x00;
	Wrbuf[1] = 0x00;
	Wrbuf[2] = 0x00;
	Wrbuf[3] = 0x00;
       GSLX680_I2C_Write(&addr,Wrbuf, 4);
	delayus(50);
	   
}
 
//GSLX680 Main Down
static void _GSLX680_load_fw(void)
{
	uchar addr;
	uchar Wrbuf[4];
	uint source_line=0;
	uint source_len = sizeof(GSLX680_FW)/sizeof(struct fw_data);
	

	for (source_line=0; source_line<source_len; source_line++)
	{
		addr = GSLX680_FW[source_line].offset;
		Wrbuf[0] = (char)(GSLX680_FW[source_line].val & 0x000000ff);
		Wrbuf[1] = (char)((GSLX680_FW[source_line].val & 0x0000ff00) >> 8);
		Wrbuf[2] = (char)((GSLX680_FW[source_line].val & 0x00ff0000) >> 16);
		Wrbuf[3] = (char)((GSLX680_FW[source_line].val & 0xff000000) >> 24);

		GSLX680_I2C_Write(&addr,Wrbuf, 4);
	}
	

}
//startup chip
static void _GSLX680_startup_chip(void)
{
	uchar addr;	
	uchar Wrbuf[4];

	addr = 0xe0;
	Wrbuf[0] = 0x00;
       GSLX680_I2C_Write(&addr,Wrbuf, 1);

}

//GSLX680_Initial
void TOUCH_Init(void)
{
	WAKE=1;	
	Delay1ms(20);
	WAKE=0;		
	Delay1ms(20);
	WAKE=1;		
	Delay1ms(20);
	_GSLX680_clr_reg();
	_GSLX680_reset_chip();
	_GSLX680_load_fw();
//	_GSLX680_startup_chip();
	_GSLX680_reset_chip();
	_GSLX680_startup_chip();
}


/******************************************************************************************
*Function name£ºDraw_Big_Point(u16 x,u16 y)
* Parameter£ºuint16_t x,uint16_t y xy
* Return Value£ºvoid
* Function£ºDraw touch pen nib point 2 * 2
*********************************************************************************************/		   
void Draw_Big_Point(uint x,uint y,uint colour)
{ uchar tmp1,tmp2;
	tmp1=colour>>8;tmp2=colour;
   
    Write_Dir(0x40,0x00);//The drawing mode	
	MemoryWrite_Position(x,y);//Memory write position
	LCD_CmdWrite(0x02);//Memory write Data	
	LCD_DataWrite(tmp1);
	LCD_DataWrite(tmp2);
	LCD_DataWrite(tmp1);
	LCD_DataWrite(tmp2);
	MemoryWrite_Position(x,y+1);//Memory write position
    LCD_CmdWrite(0x02);////Memory write Data					   
	LCD_DataWrite(tmp1);
	LCD_DataWrite(tmp2);
	LCD_DataWrite(tmp1);
	LCD_DataWrite(tmp2);
}






//Tp Draq Line Function Test
void TPTEST(void)
{	uchar touch_data[24] = {0};
	uchar ss[4];	
	 IT0=1;        //Falling edge trigger  
	 EX0=1;
	 EA=1;


			Active_Window(0,799,0,479);//Set the working window size
		    Text_Foreground_Color1(color_white);//Set the foreground color
			Text_Background_Color1(color_black);//Set the background color
			Write_Dir(0X8E,0X80);//Began to clear the screen (display window)
		    Chk_Busy();
		
			Write_Dir(0x40,0x80);//Set the character mode
		  	Write_Dir(0x21,0x10);//Select the internal CGROM  ISO/IEC 8859-1.
			Write_Dir(0x22,0x00);//Full alignment is disable.The text background color . Text don't rotation. 2x zoom
		  	FontWrite_Position(40,20);
		  	String("Capacitive touch screen test! Touch to display the coordinate");
		  	FontWrite_Position(40,40);
		  	String("Please wait touch initial.......");	
		  	FontWrite_Position(40,60);
		  	String("Touch screen is initialized.......");	
	 TOUCH_Init();
	PEN=1;
	while(next)
	{		FontWrite_Position(40,80);
		  	String("Touch screen initial success.");							
			if(ts_event.Key_Sta==Key_Down)        //The touch screen is pressed

			{
				EX0=0;//Close interrupt
				do
				{
					GSLX680_read_data();
					ts_event.Key_Sta=Key_Up;
		

					
					inttostr(ts_event.x1&0x0fff,ss);	
			
				  	FontWrite_Position(100,160);   //Set the display position
				  	LCD_CmdWrite(0x02);
				  	String("X =  ");



				  	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&0x0fff,ss); 
				  	FontWrite_Position(100, 240);   //Set the display position
				  	LCD_CmdWrite(0x02);
				  	String("Y =  ");


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

					Draw_Big_Point(ts_event.x1,ts_event.y1,color_red);
					Draw_Big_Point(ts_event.x2,ts_event.y2,color_green);	
					Draw_Big_Point(ts_event.x3,ts_event.y3,color_blue);
					Draw_Big_Point(ts_event.x4,ts_event.y4,color_cyan);	
					Draw_Big_Point(ts_event.x5,ts_event.y5,color_purple);
                

				}while((PEN==0)&&(next==1));
				EX0=1;
			}



    }

	 IT0=0;        //Falling edge trigger  
	 EA=0;

}













