#include "main.h"
#include "32f429_lcd.h"
#include "usart.h"
#include "GT911.h"

GT911_Dev Dev_Now,Dev_Backup;

uint8_t s_GT911_CfgParams[]=
{
  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,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,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,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,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,
  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,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,0x00,0x00,0x00,0x00
};

u16 CT_Color_table[]={Green,Blue,Red,White,Yellow};

/******************************************************************************
* Function Name  : TP_INT_Config
* Description    : Capacitive touch screen configuration
* Input          : None
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void TP_INT_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  RCC_AHB1PeriphClockCmd(CT_INT_CLK, ENABLE);
  
  /***********************GPIO Configuration***********************/
  GPIO_InitStructure.GPIO_Pin = CT_INT_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(CT_INT_GPIO_PORT, &GPIO_InitStructure);
    
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOH, EXTI_PinSource4);
  EXTI_InitStructure.EXTI_Line = CT_INT_EXTI_LINE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void INT_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  RCC_AHB1PeriphClockCmd(CT_INT_CLK, ENABLE);
  
  /***********************GPIO Configuration***********************/
  GPIO_InitStructure.GPIO_Pin = CT_INT_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(CT_INT_GPIO_PORT, &GPIO_InitStructure);
}


void TP_INT_Config2(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	    
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOH, EXTI_PinSource4);
  EXTI_InitStructure.EXTI_Line = CT_INT_EXTI_LINE;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
uint8_t Clearbuf2 = 0;
/******************************************************************************
* Function Name  : EXTI4_IRQHandler
* Description    : Touch screen interrupt
* Input          : None
* Output         : None
* Return         : None
* Attention		   : None
*******************************************************************************/
void EXTI4_IRQHandler(void)
{  
	if(EXTI_GetITStatus(CT_INT_EXTI_LINE)!= RESET )
  {	
		Dev_Now.Touch = 1;
    EXTI_ClearITPendingBit(CT_INT_EXTI_LINE);//Clears the EXTI's line pending bits.
    EXTI_ClearFlag(CT_INT_EXTI_LINE);			
  }  
}

uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
	uint8_t i;
	uint8_t ret=0;
	CT_I2C_Start();	
 	CT_I2C_Send_Byte(CT_CMD_WR);   
	CT_I2C_Wait_Ack();
	CT_I2C_Send_Byte(reg>>8);   	
	CT_I2C_Wait_Ack(); 	 										  		   
	CT_I2C_Send_Byte(reg&0XFF);   	
	CT_I2C_Wait_Ack();  
	for(i=0;i<len;i++)
	{	   
    CT_I2C_Send_Byte(buf[i]);  
		ret=CT_I2C_Wait_Ack();
		if(ret)break;  
	}
  CT_I2C_Stop();					
	return ret; 
}

void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
	uint8_t i;
 	CT_I2C_Start();	
 	CT_I2C_Send_Byte(CT_CMD_WR);  
	CT_I2C_Wait_Ack();
 	CT_I2C_Send_Byte(reg>>8);   
	CT_I2C_Wait_Ack(); 	 										  		   
 	CT_I2C_Send_Byte(reg&0XFF);   	
	CT_I2C_Wait_Ack();  
 	CT_I2C_Stop();  
	
 	CT_I2C_Start();  	 	   
	CT_I2C_Send_Byte(CT_CMD_RD);     
	CT_I2C_Wait_Ack();	   
	for(i=0;i<len;i++)
	{	   
		buf[i]=CT_I2C_Read_Byte(i==(len-1)?0:1); 
	} 
  CT_I2C_Stop();   
}

void GT911_RST_INT_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOH, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//INT PH4
	GPIO_Init(GPIOH, &GPIO_InitStructure);	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//RST PB4
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

void GT911_Reset_Sequence()
{
	GT911_RST_INT_GPIO_Init();
	
	GPIO_ResetBits(GPIOB,GPIO_Pin_4);  	//RST PB4
	delay_ms(100); 
	GPIO_ResetBits(GPIOH,GPIO_Pin_4);   //INT PH4
	delay_ms(100);
	GPIO_SetBits(GPIOB,GPIO_Pin_4);    	//RST PB4
	delay_ms(200); 
	INT_Config();
	delay_ms(100);
}

uint8_t GT911_ReadStatue(void)
{
	uint8_t buf[4];
	GT911_RD_Reg(GT911_PRODUCT_ID_REG, (uint8_t *)&buf[0], 3);
	GT911_RD_Reg(GT911_CONFIG_REG, (uint8_t *)&buf[3], 1);
	printf("TouchPad_ID:%c,%c,%c\r\nTouchPad_Config_Version:%2x\r\n",buf[0],buf[1],buf[2],buf[3]);
	return buf[3];
}

uint16_t GT911_ReadFirmwareVersion(void)
{
	uint8_t buf[2];

	GT911_RD_Reg(GT911_FIRMWARE_VERSION_REG, buf, 2);

	printf("FirmwareVersion:%2x\r\n",(((uint16_t)buf[1] << 8) + buf[0]));
	return ((uint16_t)buf[1] << 8) + buf[0];
}

void GT911_Scan(void)
{
	uint8_t buf[41];
  uint8_t Clearbuf = 0;
	uint8_t i;
	
	if (Dev_Now.Touch == 1)
	{	
		Dev_Now.Touch = 0;
		GT911_RD_Reg(GT911_READ_XY_REG, buf, 1);		

		if ((buf[0]&0x80) == 0x00)
		{
			GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
			delay_ms(10);
		}
		else
		{
			Dev_Now.TouchpointFlag = buf[0];
			Dev_Now.TouchCount = buf[0]&0x0f;
			if (Dev_Now.TouchCount > 5)
			{
				GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
				return ;
			}		
			GT911_RD_Reg(GT911_READ_XY_REG+1, &buf[1], Dev_Now.TouchCount*8);
			GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
			
			Dev_Now.Touchkeytrackid[0] = buf[1];
			Dev_Now.X[0] = ((uint16_t)buf[3] << 8) + buf[2];
			Dev_Now.Y[0] = ((uint16_t)buf[5] << 8) + buf[4];
			Dev_Now.S[0] = ((uint16_t)buf[7] << 8) + buf[6];

			Dev_Now.Touchkeytrackid[1] = buf[9];
			Dev_Now.X[1] = ((uint16_t)buf[11] << 8) + buf[10];
			Dev_Now.Y[1] = ((uint16_t)buf[13] << 8) + buf[12];
			Dev_Now.S[1] = ((uint16_t)buf[15] << 8) + buf[14];

			Dev_Now.Touchkeytrackid[2] = buf[17];
			Dev_Now.X[2] = ((uint16_t)buf[19] << 8) + buf[18];
			Dev_Now.Y[2] = ((uint16_t)buf[21] << 8) + buf[20];
			Dev_Now.S[2] = ((uint16_t)buf[23] << 8) + buf[22];

			Dev_Now.Touchkeytrackid[3] = buf[25];
			Dev_Now.X[3] = ((uint16_t)buf[27] << 8) + buf[26];
			Dev_Now.Y[3] = ((uint16_t)buf[29] << 8) + buf[28];
			Dev_Now.S[3] = ((uint16_t)buf[31] << 8) + buf[30];

			Dev_Now.Touchkeytrackid[4] = buf[33];
			Dev_Now.X[4] = ((uint16_t)buf[35] << 8) + buf[34];
			Dev_Now.Y[4] = ((uint16_t)buf[37] << 8) + buf[36];
			Dev_Now.S[4] = ((uint16_t)buf[39] << 8) + buf[38];

			for (i = 0; i< Dev_Backup.TouchCount;i++)
			{
				if(Dev_Now.Y[i]<22)Dev_Now.Y[i]=22;
				if(Dev_Now.Y[i]>460)Dev_Now.Y[i]=460;
				if(Dev_Now.X[i]<20)Dev_Now.X[i]=20;
				if(Dev_Now.X[i]>779)Dev_Now.X[i]=779;
				
				LCD_SetColors(LCD_COLOR_BLACK,LCD_COLOR_BLACK);
				LCD_DrawFullCircle(Dev_Backup.X[i],Dev_Backup.Y[i],20);		
			}
			for (i=0;i<Dev_Now.TouchCount;i++)
			{
				if(Dev_Now.Y[i]<22)Dev_Now.Y[i]=22;
				if(Dev_Now.Y[i]>460)Dev_Now.Y[i]=460;
				if(Dev_Now.X[i]<20)Dev_Now.X[i]=20;
				if(Dev_Now.X[i]>779)Dev_Now.X[i]=779;
				
				Dev_Backup.X[i] = Dev_Now.X[i];
				Dev_Backup.Y[i] = Dev_Now.Y[i];
				Dev_Backup.TouchCount = Dev_Now.TouchCount;		

				LCD_SetColors(CT_Color_table[i],LCD_COLOR_BLACK);
				LCD_DrawFullCircle(Dev_Now.X[i],Dev_Now.Y[i],20);
			}
		}	
	}
}


void GT911_TEST(void)
{
  uint8_t config_Checksum = 0,i;
	
	GT911_Reset_Sequence();
	CT_I2C_Init();		
	
	TP_INT_Config2();
	delay_ms(300); 
	
	//debug 
	GT911_RD_Reg(GT911_CONFIG_REG, (uint8_t *)&s_GT911_CfgParams[0], 186);

	for(i=0;i<sizeof(s_GT911_CfgParams)-2;i++)
	{
		config_Checksum += s_GT911_CfgParams[i];
		
		printf("0x%02X  ", s_GT911_CfgParams[i]);
		if ((i+1)%10==0)
			printf("\r\n");
	}
	printf("0x%02X  0x%02X\r\nconfig_Checksum=0x%2X\r\n", s_GT911_CfgParams[184],s_GT911_CfgParams[185], ((~config_Checksum)+1)&0xff);

	if (s_GT911_CfgParams[184] == (((~config_Checksum)+1)&0xff))
	{
		printf("READ CONFIG SUCCESS!\r\n");
		printf("%d*%d\r\n",s_GT911_CfgParams[2]<<8|s_GT911_CfgParams[1],s_GT911_CfgParams[4]<<8|s_GT911_CfgParams[3]);
		
		if ((GT911_MAX_WIDTH != (s_GT911_CfgParams[2]<<8|s_GT911_CfgParams[1])) || (GT911_MAX_HEIGHT != (s_GT911_CfgParams[4]<<8|s_GT911_CfgParams[3])))
		{	
			s_GT911_CfgParams[1] = GT911_MAX_WIDTH&0xff;
			s_GT911_CfgParams[2] = GT911_MAX_WIDTH>>8;
			s_GT911_CfgParams[3] = GT911_MAX_HEIGHT&0xff;
			s_GT911_CfgParams[4] = GT911_MAX_HEIGHT>>8;
			s_GT911_CfgParams[185] = 1;
			
			printf("%d*%d\r\n",s_GT911_CfgParams[2]<<8|s_GT911_CfgParams[1],s_GT911_CfgParams[4]<<8|s_GT911_CfgParams[3]);
		
			config_Checksum = 0;
			for(i=0;i<sizeof(s_GT911_CfgParams)-2;i++)
			{
				config_Checksum += s_GT911_CfgParams[i];
			}
			s_GT911_CfgParams[184] = (~config_Checksum)+1;
		
			printf("config_Checksum=0x%2X\r\n",s_GT911_CfgParams[184]);
			
			printf("\r\n*************************\r\n");
			for(i=0;i<sizeof(s_GT911_CfgParams);i++)
			{			
				printf("0x%02X  ", s_GT911_CfgParams[i]);
				if ((i+1)%10==0)
					printf("\r\n");
			}
			printf("\r\n*************************\r\n");
			GT911_WR_Reg(GT911_CONFIG_REG, (uint8_t *)s_GT911_CfgParams, sizeof(s_GT911_CfgParams));
			
			
			GT911_RD_Reg(GT911_CONFIG_REG, (uint8_t *)&s_GT911_CfgParams[0], 186);

			config_Checksum = 0;
			for(i=0;i<sizeof(s_GT911_CfgParams)-2;i++)
			{
				config_Checksum += s_GT911_CfgParams[i];
				
				printf("0x%02X  ", s_GT911_CfgParams[i]);
				if ((i+1)%10==0)
					printf("\r\n");
			}
			printf("0x%02X  ", s_GT911_CfgParams[184]);
			printf("0x%02X  ", s_GT911_CfgParams[185]);
			printf("\r\n");
			printf("config_Checksum=0x%2X\r\n",((~config_Checksum)+1)&0xff);
		}
		
	}
//debug end
	GT911_ReadFirmwareVersion();

	while(1)
	{
		GT911_Scan();
	}
}
