I.MX6U-ALPHA开发板(多点电容触摸屏实验)

一、多点电容触摸屏简介

​ 1、多点触摸,不需要按下。
​ 2、电容触摸屏需要一个IC驱动控制的,一般是I2C接口,多点触摸屏驱动最终就是一个I2C外设驱动。
​ 正点原子电容触摸屏,4.3寸都是GT9147 IC,7寸2款,一个是FT5206、一个是FT5426。
​ 触摸屏IP:
​ CT_INT,触摸中断线,连接到了GPIO1_IO09
​ I2C2_SCL:连接到了UART5_TXD
​ I2C2_SDA:连接到了UART5_RXD
​ RESET:连接到了SNVS_TAMPER9

电容触摸芯片输出的触摸点坐标信息为对应的屏幕像素点信息,因此不需要校准。电阻屏需要校准。

二、FT54x6/FT52x6电容触摸芯片简介

​ 1、IIC接口,最大400KHz
​ 2、正点原子7寸屏幕FT5426的IIC地址为0X38.
​ 3、需要用到的寄存器
​ DEVICE_MODE 0X00,需要设置为0X0,表示正常运行模式。
​ ID_G_LIB_VERSION_H以及ID_G_LIB_VERSION_L 0XA1和0XA2。表示固件版本号。
​ ID_G_MODE 0XA4,设置为1,表示采用中断方式上报触摸信息。
​ TD_STATUS 0X02,当前触摸点的个数,1~5。
​ TOUCH1_XH 0X03开始记录着触摸屏的触摸点坐标信息,一个触摸点6个寄存器,一共需要5*6=30个寄存器。一直读取到0X20
​ 一个触摸点坐标信息用12bit表示,其中H的bit3:0这4个bit为高4位,L寄存器的bit7:0为低8位。
对于XH寄存器,bit7:6表示事件,很重要。
YH寄存器的bit7:4表示触摸ID,

三、实验程序编写

//bsp_ft5xx6.h
#ifndef _FT5XX6_H
#define _FT5XX6_H


#include "imx6ul.h"
#include "bsp_gpio.h"

/* 宏定义 */
#define FT5426_ADDR				0X38	/* FT5426设备地址 		*/

#define FT5426_DEVICE_MODE		0X00 	/* 模式寄存器 			*/
#define FT5426_IDGLIB_VERSION	0XA1 	/* 固件版本寄存器 			*/
#define FT5426_IDG_MODE			0XA4	/* 中断模式				*/
#define FT5426_TD_STATUS		0X02	/* 触摸状态寄存器 			*/
#define FT5426_TOUCH1_XH		0X03	/* 触摸点坐标寄存器,
										 * 一个触摸点用4个寄存器存储坐标数据*/
										 
#define FT5426_XYCOORDREG_NUM	30		/* 触摸点坐标寄存器数量 */
#define FT5426_INIT_FINISHED	1		/* 触摸屏初始化完成 			*/
#define FT5426_INIT_NOTFINISHED	0		/* 触摸屏初始化未完成 			*/

#define FT5426_TOUCH_EVENT_DOWN			0x00	/* 按下 		*/
#define FT5426_TOUCH_EVENT_UP			0x01	/* 释放 		*/
#define FT5426_TOUCH_EVENT_ON			0x02	/* 接触 		*/
#define FT5426_TOUCH_EVENT_RESERVED		0x03	/* 没有事件 */

/* 触摸屏结构体 */
struct ft5426_dev_struc
{	
	unsigned char initfalg;		/* 触摸屏初始化状态 */
	unsigned char intflag;		/* 标记中断有没有发生 */
	unsigned char point_num;	/* 触摸点 		*/
	unsigned short x[5];		/* X轴坐标 	*/
	unsigned short y[5];		/* Y轴坐标 	*/

};

extern struct ft5426_dev_struc ft5426_dev;

/* 函数声明 */
void ft5426_init(void);

void gpio1_io9_irqhandler(void);
unsigned char ft5426_write_byte(unsigned char addr,unsigned char reg, unsigned char data);
unsigned char ft5426_read_byte(unsigned char addr,unsigned char reg);
void ft5426_read_len(unsigned char addr,unsigned char reg,unsigned char len,unsigned char *buf);
void ft5426_read_tpnum(void);
void ft5426_read_tpcoord(void);

#endif

//bsp_ft5xx6.c
#include "bsp_ft5xx6.h"
#include "bsp_i2c.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "stdio.h"

struct ft5426_dev_struc ft5426_dev;

//初始化触摸屏,其实就是初始化FT5426
void ft5426_init(void)
{
	unsigned char reg_value[2];

	ft5426_dev.initfalg = FT5426_INIT_NOTFINISHED;
	int i;
	for( i = 0; i < 5; i++ )
	{	/* 避免编译器自动赋值 */
		ft5426_dev.x[i] = 0;
		ft5426_dev.y[i] = 0;
	}
	ft5426_dev.point_num = 0;

	/* 1、初始化IIC2 IO
     * I2C2_SCL -> UART5_TXD
     * I2C2_SDA -> UART5_RXD
     */
	IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL,1);
	IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA,1);

	/* 配置I2C2 IO属性	
	 *bit 16:0 HYS关闭
	 *bit [15:14]: 1 默认47K上拉
	 *bit [13]: 1 pull功能
	 *bit [12]: 1 pull/keeper使能 
	 *bit [11]: 0 关闭开路输出
	 *bit [7:6]: 10 速度100Mhz
	 *bit [5:3]: 110 驱动能力为R0/6
	 *bit [0]: 1 高转换率
	 */
	IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL,0x70B0);
	IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA,0X70B0);
	
	/* 2、初始化触摸屏中断IO和复位IO */
	gpio_pin_config_t ctintpin_config;

	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO09_GPIO1_IO09,0);		/* 复用为GPIO1_IO9 */
	IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0);/* 复用为GPIO5_IO9 */
	
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0xF080);
	IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0X10B0);

	/* 中断IO初始化 */
	ctintpin_config.direction = kGPIO_DigitalInput;
	ctintpin_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
	gpio_init(GPIO1, 9, &ctintpin_config);

	GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);				/* 使能GIC中对应的中断 */
	system_register_irqhandler(GPIO1_Combined_0_15_IRQn, (system_irq_handler_t)gpio1_io9_irqhandler, NULL);	/* 注册中断服务函数 */
	gpio_enableint(GPIO1, 9);								/* 使能GPIO1_IO18的中断功能 */

	/* 复位IO初始化 */
    ctintpin_config.direction=kGPIO_DigitalOutput;	
    ctintpin_config.interruptMode=kGPIO_NoIntmode;	
    ctintpin_config.outputLogic=1;					   
    gpio_init(GPIO5, 9, &ctintpin_config); 

	/* 3、初始化I2C */
	i2c_init(I2C2);	

	/* 4、初始化FT5426 */
	gpio_pinwrite(GPIO5, 9, 0);	/* 复位FT5426 */
	delayms(20);
	gpio_pinwrite(GPIO5, 9, 1); /* 停止复位FT5426 */
	delayms(20);

	ft5426_write_byte(FT5426_ADDR, FT5426_DEVICE_MODE, 0); 	/* 进入正常模式 				*/
	ft5426_write_byte(FT5426_ADDR, FT5426_IDG_MODE, 1); 	/* FT5426中断模式 			*/

	
	ft5426_read_len(FT5426_ADDR, FT5426_IDGLIB_VERSION, 2, reg_value);
	printf("Touch Frimware Version:%#X\r\n", ((unsigned short)reg_value[0] << 8) + reg_value[1]);
	
	ft5426_dev.initfalg = FT5426_INIT_FINISHED;	/* 标记FT5426初始化完成 */
	ft5426_dev.intflag = 0;
}

//GPIO1_IO9最终的中断处理函数
 void gpio1_io9_irqhandler(void)
{ 
	if(ft5426_dev.initfalg == FT5426_INIT_FINISHED)
	{
		//ft5426_dev.intflag = 1;
		ft5426_read_tpcoord();
	}
	gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */
}


//向FT5429写入数据
//addr: 设备地址
//reg : 要写入的寄存器
//data: 要写入的数据
//返回操作结果
unsigned char ft5426_write_byte(unsigned char addr,unsigned char reg, unsigned char data)
{
    unsigned char status=0;
    unsigned char writedata=data;
    struct i2c_transfer masterXfer;
	
    /* 配置I2C xfer结构体 */
   	masterXfer.slaveAddress = addr; 			/* 设备地址 				*/
    masterXfer.direction = kI2C_Write;			/* 写入数据 				*/
    masterXfer.subaddress = reg;				/* 要写入的寄存器地址 			*/
    masterXfer.subaddressSize = 1;				/* 地址长度一个字节 			*/
    masterXfer.data = &writedata;				/* 要写入的数据 				*/
    masterXfer.dataSize = 1;  					/* 写入数据长度1个字节			*/

    if(i2c_master_transfer(I2C2, &masterXfer))
        status=1;
        
    return status;
}

//从FT5426读取一个字节的数据
//addr: 设备地址
//reg : 要读取的寄存器
//返回读取到的数据。
unsigned char ft5426_read_byte(unsigned char addr,unsigned char reg)
{
	unsigned char val=0;
	
	struct i2c_transfer masterXfer;	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 1;				/* 地址长度一个字节 			*/
    masterXfer.data = &val;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = 1;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);

	return val;
}

//从FT5429读取多个字节的数据
//addr: 设备地址
//reg : 要读取的开始寄存器地址
//len : 要读取的数据长度.
//buf : 读取到的数据缓冲区
void ft5426_read_len(unsigned char addr,unsigned char reg,unsigned char len,unsigned char *buf)
{	
	struct i2c_transfer masterXfer;	
	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 1;				/* 地址长度一个字节 			*/
    masterXfer.data = buf;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = len;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);
} 

//读取当前触摸点个数
void ft5426_read_tpnum(void)
{
	ft5426_dev.point_num = ft5426_read_byte(FT5426_ADDR, FT5426_TD_STATUS);
}

//读取当前所有触摸点的坐标
void ft5426_read_tpcoord(void)
{
	unsigned char i = 0;
	unsigned char type = 0;
	//unsigned char id = 0;
	unsigned char pointbuf[FT5426_XYCOORDREG_NUM];
	
	ft5426_dev.point_num = ft5426_read_byte(FT5426_ADDR, FT5426_TD_STATUS);

	/*
  	 * 从寄存器FT5426_TOUCH1_XH开始,连续读取30个寄存器的值,这30个寄存器
  	 * 保存着5个点的触摸值,每个点占用6个寄存器。
	 */
	ft5426_read_len(FT5426_ADDR, FT5426_TOUCH1_XH, FT5426_XYCOORDREG_NUM, pointbuf);
		
	for(i = 0; i < ft5426_dev.point_num ; i++)
	{
		unsigned char *buf = &pointbuf[i * 6];
		/* 以第一个触摸点为例,寄存器TOUCH1_XH(地址0X03),各位描述如下:
		 * bit7:6  Event flag  0:按下 1:释放 2:接触 3:没有事件
		 * bit5:4  保留
		 * bit3:0  X轴触摸点的11~8位。
		 */
		ft5426_dev.x[i] = ((buf[2] << 8) | buf[3]) & 0x0fff;
		ft5426_dev.y[i] = ((buf[0] << 8) | buf[1]) & 0x0fff;
		
		type = buf[0] >> 6;	/* 获取触摸类型 */
		

		/* 以第一个触摸点为例,寄存器TOUCH1_YH(地址0X05),各位描述如下:
		 * bit7:4  Touch ID  触摸ID,表示是哪个触摸点
		 * bit3:0  Y轴触摸点的11~8位。
		 */
		//id = (buf[2] >> 4) & 0x0f;
		
		if(type == FT5426_TOUCH_EVENT_DOWN || type == FT5426_TOUCH_EVENT_ON )/* 按下 	*/
		{
		
		} else  {	/* 释放 */	
			
		}
	}	
}


//bsp_gt9147.h
#ifndef _GT9147_H
#define _GT9147_H


#include "imx6ul.h"
#include "bsp_gpio.h"

/* 宏定义 */
#define GT9147_ADDR				0X14	/* GT9147设备地址 		    */

#define GT_CTRL_REG 	        0X8040  /* GT9147控制寄存器         */
#define GT_MODSW_REG 	        0X804D  /* GT9147模式切换寄存器        */
#define GT_CFGS_REG 	        0X8047  /* GT9147配置起始地址寄存器    */
#define GT1151_CFGS_REG 	    0X8050  /* GT1151配置起始地址寄存器    */
#define GT_CHECK_REG 	        0X80FF  /* GT9147校验和寄存器       */
#define GT_PID_REG 		        0X8140  /* GT9147产品ID寄存器       */

#define GT_GSTID_REG 	        0X814E  /* GT9147当前检测到的触摸情况 */
#define GT_TP1_REG 		        0X8150  /* 第一个触摸点数据地址 */
#define GT_TP2_REG 		        0X8158	/* 第二个触摸点数据地址 */
#define GT_TP3_REG 		        0X8160  /* 第三个触摸点数据地址 */
#define GT_TP4_REG 		        0X8168  /* 第四个触摸点数据地址  */
#define GT_TP5_REG 		        0X8170	/* 第五个触摸点数据地址   */
										 
#define GT9147_XYCOORDREG_NUM	30		/* 触摸点坐标寄存器数量 */
#define GT9147_INIT_FINISHED	1		/* 触摸屏初始化完成 			*/
#define GT9147_INIT_NOTFINISHED	0		/* 触摸屏初始化未完成 			*/


/* 触摸屏结构体 */
struct gt9147_dev_struc
{	
	unsigned char initfalg;		/* 触摸屏初始化状态 */
	unsigned char intflag;		/* 标记中断有没有发生 */
	unsigned char point_num;	/* 触摸点 		*/
	unsigned short x[5];		/* X轴坐标 	*/ 
	unsigned short y[5];		/* Y轴坐标 	*/
};

extern struct gt9147_dev_struc gt9147_dev;
extern int gt_init_fail;

/* 函数声明 */
void gt9147_init(void);

void gt9147_irqhandler(void);
unsigned char gt9147_write_byte(unsigned char addr,unsigned int reg, unsigned char data);
unsigned char gt9147_read_byte(unsigned char addr,unsigned int reg);
void gt9147_read_len(unsigned char addr,unsigned int reg,unsigned int len,unsigned char *buf);
void gt9147_write_len(unsigned char addr,unsigned int reg,unsigned int len,unsigned char *buf);
void gt9147_read_tpnum(void);
void gt9147_read_tpcoord(void);
void gt9147_send_cfg(unsigned char mode);
void gt9147_read_tpcoord(void);
#endif


//bsp_gt9147.c

#include "bsp_gt9147.h"
#include "bsp_i2c.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "stdio.h"

/*
 * GT9147配置参数表
 * 第一个字节为版本号(0X61),必须保证新的版本号大于等于GT9147内部
 * flash原有版本号,才会更新配置.
 */
u8 GT9147_CFG_TBL[]=
{ 
	0x41,0xe0,0x01,0x10,0x01,0x05,0x0d,0x00,0x01,0x08,
	0x28,0x05,0x50,0x32,0x03,0x05,0x00,0x00,0xff,0xff,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x28,0x0a,
	0x17,0x15,0x31,0x0d,0x00,0x00,0x02,0x9b,0x03,0x25,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,
	0x00,0x0f,0x94,0x94,0xc5,0x02,0x07,0x00,0x00,0x04,
	0x8d,0x13,0x00,0x5c,0x1e,0x00,0x3c,0x30,0x00,0x29,
	0x4c,0x00,0x1e,0x78,0x00,0x1e,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,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,
	0x18,0x1a,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0xff,0xff,0x00,0x02,0x04,0x05,0x06,0x08,0x0a,0x0c,
	0x0e,0x1d,0x1e,0x1f,0x20,0x22,0x24,0x28,0x29,0xff,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0xff,0xff,0xff,0xff,
};

struct gt9147_dev_struc gt9147_dev;
int gt_init_fail = 0;

//初始化触摸屏,其实就是初始化GT9147
void gt9147_init(void)
{
    unsigned char temp[7]; 
  
	gpio_pin_config_t ctintpin_config;
	gpio_pin_config_t ctretpin_config;
	gt9147_dev.initfalg = GT9147_INIT_NOTFINISHED;
	int i;
	for( i = 0; i < 5; i++ )
	{	/* 避免编译器自动赋值 */
		gt9147_dev.x[i] = 0;
		gt9147_dev.y[i] = 0;
	}
	gt9147_dev.point_num = 0;
	/* 1、初始化IIC2 IO
     * I2C2_SCL -> UART5_TXD
     * I2C2_SDA -> UART5_RXD
     */
	IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL,1);
	IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA,1);

	/* 配置I2C2 IO属性	
	 *bit 16:0 HYS关闭
	 *bit [15:14]: 1 默认47K上拉
	 *bit [13]: 1 pull功能
	 *bit [12]: 1 pull/keeper使能 
	 *bit [11]: 0 关闭开路输出
	 *bit [7:6]: 10 速度100Mhz
	 *bit [5:3]: 110 驱动能力为R0/6
	 *bit [0]: 1 高转换率
	 */
	IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL, 0x70B0);
	IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA, 0X70B0);
	
	/* 2、初始化触摸屏中断IO和复位IO */
	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO09_GPIO1_IO09,0);		/* 复用为GPIO1_IO9 */
	IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0);/* 复用为GPIO5_IO9 */
	
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0x10B0);
	IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0X10B0);

	/* 中断IO初始化 */
	ctintpin_config.direction = kGPIO_DigitalOutput;
	ctintpin_config.outputLogic = 1;
	ctintpin_config.interruptMode = kGPIO_NoIntmode;
	gpio_init(GPIO1, 9, &ctintpin_config);

	/* 复位IO初始化 */
    ctretpin_config.direction = kGPIO_DigitalOutput;	
    ctretpin_config.interruptMode = kGPIO_NoIntmode;	
    ctretpin_config.outputLogic = 1;					   
    gpio_init(GPIO5, 9, &ctretpin_config); 

	/* 3、初始化I2C */
	i2c_init(I2C2);	

	/* 4、初始化GT9147,要严格按照GT9147时序要求 */
	gpio_pinwrite(GPIO5, 9, 0);	/* 复位GT9147 */
	delayms(10);
	gpio_pinwrite(GPIO5, 9, 1); /* 停止复位GT9147 */ 
	delayms(10);
	gpio_pinwrite(GPIO1, 9, 0);	/* 拉低INT引脚 */
	delayms(100);

    gt9147_read_len(GT9147_ADDR, GT_PID_REG, 6, temp);/* 读取产品ID */
	temp[6] = temp[4];
    temp[4] = 0;
	printf("CTP ID:%s\r\n", temp);	    /* 打印ID */
	printf("Default Ver:%#x\r\n",((temp[5]<<8) | temp[6]));   /* 打印固件版本 */

	/* 重新设置中断IO,配置为中断功能 */
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0x0080);
	ctintpin_config.direction = kGPIO_DigitalInput;
	ctintpin_config.outputLogic=0;
	temp[0]=gt9147_read_byte(GT9147_ADDR, 0x804D) && 0x3;     /* 获取中断模式 */
	switch(temp[0]) {
		case 0x0:
			printf("InterruptMode:IntRisingEdge\r\n");
			ctintpin_config.interruptMode = kGPIO_IntRisingEdge;
			break;
		case 0x1:
			printf("InterruptMode:IntFallingEdge\r\n");
			ctintpin_config.interruptMode = kGPIO_IntFallingEdge;
			break;
		case 0x2:
			printf("InterruptMode:IntLowLevel\r\n");
			ctintpin_config.interruptMode = kGPIO_IntLowLevel;
			break;
		case 0x3:
			printf("InterruptMode:IntHighLevel\r\n");
			ctintpin_config.interruptMode = kGPIO_IntHighLevel;
			break;
		default : printf("InterruptMode: Error\r\n");
			ctintpin_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
			break;
	}
	gpio_init(GPIO1, 9, &ctintpin_config);

	if(gt9147_write_byte(GT9147_ADDR, GT_CTRL_REG, 0x02))
	{
		gt_init_fail = 1;  //gt系列初始化失败
		goto done;
	}
	delayms(10);
	gt9147_write_byte(GT9147_ADDR, GT_CTRL_REG, 0);	
	GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);			/* 使能GIC中对应的中断 */
	system_register_irqhandler(GPIO1_Combined_0_15_IRQn, (system_irq_handler_t)gt9147_irqhandler, NULL);	/* 注册中断服务函数 */
	gpio_enableint(GPIO1, 9);								/* 使能GPIO1_IO09的中断功能 */
	
				
    delayms(100);
    gt9147_dev.initfalg = GT9147_INIT_FINISHED;	/* 标记GT9147初始化完成 */
	gt9147_dev.intflag = 0;
done:
	delayms(10);
}

//GPIO1_IO9最终的中断处理函数
void gt9147_irqhandler(void)
{ 
	if(gt9147_dev.initfalg == GT9147_INIT_FINISHED)
	{
		gt9147_dev.intflag = 1;
		//gt9147_write_byte(GT9147_ADDR, GT_GSTID_REG, 0); 	
		gt9147_read_tpcoord();
	}
	gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */
}

//向GT9147写入数据
//addr: 设备地址
//reg : 要写入的寄存器
//data: 要写入的数据
//返回操作结果
unsigned char gt9147_write_byte(unsigned char addr,unsigned int reg, unsigned char data)
{
    unsigned char status=0;
    unsigned char writedata=data;
    struct i2c_transfer masterXfer;
	
    /* 配置I2C xfer结构体 */
   	masterXfer.slaveAddress = addr; 			/* 设备地址 				*/
    masterXfer.direction = kI2C_Write;			/* 写入数据 				*/
    masterXfer.subaddress = reg;				/* 要写入的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = &writedata;				/* 要写入的数据 				*/
    masterXfer.dataSize = 1;  					/* 写入数据长度1个字节			*/

    if(i2c_master_transfer(I2C2, &masterXfer))
        status=1;
        
    return status;
}

//从GT9147读取一个字节的数据
//addr: 设备地址
//reg : 要读取的寄存器
//返回读取到的数据。
unsigned char gt9147_read_byte(unsigned char addr,unsigned int reg)
{
	unsigned char val=0;
	
	struct i2c_transfer masterXfer;	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = &val;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = 1;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);

	return val;
}

//从GT9147读取多个字节的数据
//addr: 设备地址
//reg : 要读取的开始寄存器地址
//len : 要读取的数据长度.
//buf : 读取到的数据缓冲区
void gt9147_read_len(unsigned char addr,unsigned int reg,unsigned int len,unsigned char *buf)
{	
	struct i2c_transfer masterXfer;	
	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = buf;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = len;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);
} 

//向GT9147多个寄存器写入数据
//addr: 设备地址
//reg : 要写入的开始寄存器地址
//len : 要写入的数据长度.
//buf : 写入到的数据缓冲区
void gt9147_write_len(unsigned char addr,unsigned int reg,unsigned int len, unsigned char *buf)
{	
	struct i2c_transfer masterXfer;	
	
	masterXfer.slaveAddress = addr;				/* 设备地址         */
    masterXfer.direction = kI2C_Write;			/* 读取数据 	    */
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 */
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节     */
    masterXfer.data = buf;						/* 接收数据缓冲区 	    */
    masterXfer.dataSize = len;					/* 读取数据长度1个字节  */
	i2c_master_transfer(I2C2, &masterXfer);
} 

//发送GT9147配置参数
//mode: 0,参数不保存到flash
//      1,参数保存到flash
void gt9147_send_cfg(unsigned char mode)
{
	unsigned char buf[2];
	unsigned int i = 0;

	buf[0] = 0;
	buf[1] = mode;	/* 是否写入到GT9147 FLASH?  即是否掉电保存 */
	for(i = 0; i < (sizeof(GT9147_CFG_TBL)); i++) /* 计算校验和 */
        buf[0] += GT9147_CFG_TBL[i];            
    buf[0] = (~buf[0]) + 1;

    /* 发送寄存器配置 */
    gt9147_write_len(GT9147_ADDR, GT_CFGS_REG, sizeof(GT9147_CFG_TBL), GT9147_CFG_TBL);
    gt9147_write_len(GT9147_ADDR, GT_CHECK_REG, 2, buf);/* 写入校验和,配置更新标记 */
} 

const u16 GT9147_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};

//读取当前所有触摸点的坐标
void gt9147_read_tpcoord(void)
{
	u8 buf[4];
	u8 i = 0;
	u8 regvalue = 0;

	regvalue = gt9147_read_byte(GT9147_ADDR, GT_GSTID_REG);
	gt9147_write_byte(GT9147_ADDR, GT_GSTID_REG, 0x00);
	gt9147_dev.point_num = regvalue & 0XF; /* 计算读取了多少个点 */
	/* 读取当前所有的触摸坐标值 */
	for(i = 0; i < gt9147_dev.point_num; i++)
	{
		gt9147_read_len(GT9147_ADDR, GT9147_TPX_TBL[i], 4, buf);	/* 读取坐标值 */
		gt9147_dev.x[i] = ((u16)buf[1] << 8) + buf[0];
		gt9147_dev.y[i] = (((u16)buf[3] << 8) + buf[2]);				
	} 
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值