我的RTOS 之六 — Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」

我的RTOS 之六 — Touch移植(s5pv210+threadx+ucgui+touch)

大家好,又见面了,我是全栈君。

非常久没有关注RTOS了,所以也一直没有更新。近期闲了,把GPIO I2C调通了。简单移植了Touch。在S5PV210上使用。

调试I2C时。废了非常多周折,最后借助示波器才发现一个小小的错误。折腾了非常久非常久。

简要说下步骤:

1、首先I2C驱动,使用GPIO 我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」I2C的方式

#include <stdio.h>
#include <touch.h>

#define DELAY  10

#define SDA 0
#define SCL 1

#define 	GPD1CON 	(*(volatile unsigned long *) 0xE02000C0)
#define 	GPD1DAT		(*(volatile unsigned long *) 0xE02000C4)
#define 	GPD1PUD		(*(volatile unsigned long *) 0xE02000C8)
#define 	GPD1DRV		(*(volatile unsigned long *) 0xE02000CC)



#define SDA2_SET_INPUT (GPD1CON &= ~(0xf<<16))
#define SDA2_SET_OUTPUT (GPD1CON = (GPD1CON & (~(0x0f<<16))) | (0x1<<16))
#define SCL2_SET_INPUT (GPD1CON &= ~(0xf<<20));
#define SCL2_SET_OUTPUT (GPD1CON = (GPD1CON & (~(0x0f<<20))) | (0x1<<20))

#define SDA2_SET_VALUE(x) (GPD1DAT = (GPD1DAT & ~(1<<4)) | (x << 4))
#define SCL2_SET_VALUE(x) (GPD1DAT = (GPD1DAT & ~(1<<5)) | (x << 5))

#define SDA2_GET_VALUE ((GPD1DAT & (1<<4)) > 0 ? 1:0)
#define SCL2_GET_VALUE ((GPD1DAT & (1<<5)) > 0 ?

1:0)void gpio_i2c_init(void){ GPD1DRV = (GPD1DRV & ~(0x5 << 10) | (0x5 << 10)); GPD1PUD = (GPD1DRV & ~(0xf << 10) | 0xa << 10); SCL2_SET_OUTPUT; SDA2_SET_OUTPUT; SDA2_SET_VALUE(1); SCL2_SET_VALUE(1); }void i2c_start(void){ SCL2_SET_OUTPUT; SDA2_SET_OUTPUT; SDA2_SET_VALUE(1); SCL2_SET_VALUE(1); udelay(DELAY); SDA2_SET_VALUE(0); udelay(DELAY); SCL2_SET_VALUE(0); udelay(DELAY);}void i2c_stop(void){ SCL2_SET_OUTPUT; SDA2_SET_OUTPUT; SDA2_SET_VALUE(0); SCL2_SET_VALUE(0); udelay(DELAY); SCL2_SET_VALUE(1); udelay(DELAY); SDA2_SET_VALUE(1); udelay(DELAY);}void i2c_send_ack(unsigned char ack){ SCL2_SET_OUTPUT; SDA2_SET_OUTPUT; if(ack) SDA2_SET_VALUE(1); else SDA2_SET_VALUE(0); udelay(DELAY); SCL2_SET_VALUE(1); udelay(DELAY); SCL2_SET_VALUE(0); udelay(DELAY); }char i2c_receive_ack(void){ char rc = 0; SCL2_SET_OUTPUT; SDA2_SET_INPUT; SCL2_SET_VALUE(1); udelay(DELAY); if(SDA2_GET_VALUE) { rc = 1; } SCL2_SET_VALUE(0); SDA2_SET_OUTPUT; SDA2_SET_VALUE(1); return rc;}unsigned char i2c_send_byte(unsigned char send_byte){ unsigned char rc = 0; unsigned char out_mask = 0x80; unsigned char value; unsigned char count = 8; SDA2_SET_OUTPUT; SCL2_SET_OUTPUT; while(count > 0) { value = ((send_byte & out_mask) ?

1 : 0); if (value == 1) { SDA2_SET_VALUE(1); } else { SDA2_SET_VALUE(0); } udelay(DELAY); SCL2_SET_VALUE(1); udelay(DELAY); SCL2_SET_VALUE(0); udelay(DELAY); out_mask >>= 1; count--; } SDA2_SET_VALUE(1); rc = i2c_receive_ack(); return rc;}void i2c_read_byte(unsigned char *buffer, unsigned char ack){ unsigned char count = 0x08; unsigned char data = 0x00; unsigned char temp = 0; SDA2_SET_INPUT; SCL2_SET_OUTPUT; while(count > 0) { SCL2_SET_VALUE(1); udelay(DELAY); temp = SDA2_GET_VALUE; data <<= 1; if (temp) data |= 0x01; SCL2_SET_VALUE(0); udelay(DELAY); count--; } i2c_send_ack(ack);//0 = ACK 1 = NACK *buffer = data; }int gpio_i2c_master_send(unsigned int SlaveAddr, unsigned char *Data, unsigned int length){ unsigned int i, j; int rc; SlaveAddr = (SlaveAddr << 1) & ~0x01; i2c_start(); rc = i2c_send_byte(SlaveAddr); if(rc){ printf("i2c_send_byte no ack 1\n"); return -1; } for(j = 0; j < length; j++) { rc = i2c_send_byte(Data[j]);//发送data if(rc){ printf("i2c_send_byte no ack 2\n"); return -1; } } i2c_stop();//停止信号 udelay(10); return 0;}int gpio_i2c_master_recv(unsigned int SlaveAddr, unsigned char *Data, unsigned int length){ unsigned int i, j; unsigned int data; int rc; SlaveAddr = (SlaveAddr << 1) | 0x01; i2c_start(); rc = i2c_send_byte(SlaveAddr); if(rc) { printf("i2c_read_byte no ack 1\n"); return -1; } for(j=0; j<length; j++){ i2c_read_byte(Data++, !(length - j -1));//读取数据; } i2c_stop();//停止信号 return length;}int i2c_read_data(unsigned int SlaveAddr, char *reg, unsigned char *values, int length){ int ret; int count = 0;retry: /* select register*/ ret = gpio_i2c_master_send(SlaveAddr, reg , 1); if (ret < 0) { udelay(DELAY * 2); if (++count < 2) goto retry; return ret; } /* for setup tx transaction. */ udelay(DELAY); ret = gpio_i2c_master_recv(SlaveAddr, values , length); if (ret < 0) return ret; udelay(DELAY); return length;}

2、Touch驱动

Touch IC为 FT5406, slave地址为0x70.

借助博友的一页芯片资料,写了最简单的单点读取:

我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」

多点也非常easy。能够參考android 多点触控协议上报点

#include <touch.h>
#include <exception.h>

struct touch_data touch_data;

int touch_irq()
{
	int i;
	int num = 0;
	int x, y;
	char reg[1] = {0};
	unsigned char buf[10];
	
	i2c_read_data(0x38, reg, buf, 7);

	if((num = (buf[2] & 0x0f)) == 0)
	{
		if(touch_data.isPress)
		{
			touch_data.isPress = 0;
			touch_data.x = -1;
			touch_data.y = -1;
			touch_event(touch_data.x, touch_data.y);
		}
		//printf("release\r\n");
		return 0;
	}
	x = (buf[3]&0x0f) << 8 | buf[4];
	y = (buf[5]&0x0f) << 8 | buf[6];
	//printf("num:%d, x:%d, y:%d\r\n", num, x, y);
	touch_data.x		= x;
	touch_data.y		= y;
	if(touch_data.isPress  == 0)
		touch_data.isPress  = 1;
	touch_event(touch_data.x, touch_data.y);
	return 0;
}

void touch_init(void)
{
	unsigned char uc_reg_value;
	unsigned char uc_reg_addr;
	unsigned char buf[1];
	unsigned char dst[1];

	touch_int_setup();
	
	i2c_read_data(0x38, buf, dst, 1);
	printf("touch fw:0x%x\r\n", dst[0]);
	buf[0] = 0x88;
	i2c_read_data(0x38, buf, dst, 1);
	printf("report rate:0x%x\r\n", dst[0] * 10);
	buf[0] = 0x80;
	i2c_read_data(0x38, buf, dst, 1);
	printf("touch threshold:0x%x\r\n", dst[0] * 4);

	intc_enable(NUM_EINT14);
}

在touch_init 初始化中可以取到touch固件信息。就说明
我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」i2c通信正常了。

3、看下效果^^

我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」

我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」

我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)「建议收藏」

最后两张的动画比較卡。

4:、存在问题及缺点

因为是电容屏,中断出发,触摸的时候。会不停的上报中断,会导致其它线程block。发生卡顿的情况,尤其画面比較复杂的时候。后期能够採取查询的方法,放在单独的线程其中或者减少touch的报点率;

另外就是lcd仅仅有一层framebuffer,多层显示倒是ucgui的效率低下,后期优化能够同一时候打开至少两个framebuffer。

5、源代码

http://download.csdn.net/detail/liujia2100/8859911

后期尝试移植lwip,搭配arduino。物联网^^.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115899.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SIFT特征点提取「建议收藏」

    SIFT特征点提取「建议收藏」计算机视觉中的特征点提取算法比较多,但SIFT除了计算比较耗时以外,其他方面的优点让其成为特征点提取算法中的一颗璀璨的明珠。SIFT算法的介绍网上有很多比较好的博客和文章,我在学习这个算法的过程中也参看网上好些资料,即使评价比较高的文章,作者在文章中对有些比较重要的细节、公式来历没有提及,可能写博客的人自己明白,也觉得简单,因此就忽略了这些问题,但是对刚入门的人来说,看这些东西,想搞清楚这些是怎么

    2022年6月16日
    38
  • Hive左连接_oracle左外连接

    Hive左连接_oracle左外连接CREATEEXTERNALTABLEIFNOTEXISTSa(telnoSTRING,otherSTRING)PARTITIONEDBY(dayString)ROWFORMATDELIMITEDFIELDSTERMINATEDBY’|’;CREATEEXTERNALTABLEIFNOTEXISTSb(telnoSTRI…

    2022年9月18日
    0
  • 从零开始学习Android开发[通俗易懂]

    从零开始学习Android开发[通俗易懂]1.首先有一点点JAVA的基础知识建议阅读:https://www.runoob.com/java/java-basic-syntax.html讲的比较细,只看到高阶之前即可。2.推荐《第一行代码:Android(第2版)》第一行代码第二版,被Android开发者誉为“Android学习第一书”。全书系统全面、循序渐进地介绍了Android软件开发的必备知识、经验和技巧。…

    2022年6月25日
    18
  • Mac 破解zip压缩文件密码详解

    Mac 破解zip压缩文件密码详解使用fcrackzip来破解zip类型压缩文件fcrackzip是一款专门破解zip类型压缩文件密码的工具,工具破解速度还是可以的,能用字典和指定字符集破解,适用于Linux、MacOS系统。如果你的电脑没有安装brew,需要执行下面命令行/usr/bin/ruby-e"$(curl-fsSLhttps://raw.githubusercontent.com/Homebr…

    2022年5月1日
    460
  • tl494cn逆变器电路图_用TL494制作的逆变电源[通俗易懂]

    tl494cn逆变器电路图_用TL494制作的逆变电源[通俗易懂]TL494集成块广泛应用在开关电源,其内部集成有PWM、三角波发生器、电池欠压检测,+5V电压基准等电路,具有外接元件少,控制稳定的特点。笔者在网上查阅大量资料,自制了一款准正弦波300W逆变器,采用直流12V电瓶供电,可供小功率单相电机、日光灯等电感性负载用电,电路如附图所示。该逆变板工作频率由TL494⑤、⑥脚外接阻容元件确定,本例为2.2kHz左右。该频率的大小直接影响功率场效应管的功率损耗…

    2022年6月3日
    152
  • 十进制小数转换为二进制小数采用方法为乘2取整法?_小数点二进制转10进制

    十进制小数转换为二进制小数采用方法为乘2取整法?_小数点二进制转10进制十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的整数部分为零,或者整数部分为1,此时0或1为二进制的最后一位。或者达到所要求的精度为止。  然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有…

    2022年9月24日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号