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

发布者:科技创新实践者最新更新时间:2024-12-20 来源: cnblogs关键字:RTOS  s5pv210 手机看文章 扫描二维码
随时随地手机看文章

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

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


简要说下步骤:

1、首先I2C驱动,使用GPIO I2C的方式


#include

#include


#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 1n');

return -1;

}


for(j = 0; j < length; j++) {

rc = i2c_send_byte(Data[j]);//发送data

if(rc){

printf('i2c_send_byte no ack 2n');

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 1n');

return -1;

}


for(j=0; 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.

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



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


#include 
#include 

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('releasern');
		return 0;
	}
	x = (buf[3]&0x0f) << 8 | buf[4];
	y = (buf[5]&0x0f) << 8 | buf[6];
	//printf('num:%d, x:%d, y:%drn', 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%xrn', dst[0]);
	buf[0] = 0x88;
	i2c_read_data(0x38, buf, dst, 1);
	printf('report rate:0x%xrn', dst[0] * 10);
	buf[0] = 0x80;
	i2c_read_data(0x38, buf, dst, 1);
	printf('touch threshold:0x%xrn', dst[0] * 4);

	intc_enable(NUM_EINT14);
}


在touch_init 初始化中可以取到touch固件信息。就说明i2c通信正常了。



3、看下效果^^






最后两张的动画比較卡。



4:、存在问题及缺点

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

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


5、源代码

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


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


关键字:RTOS  s5pv210 引用地址:我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)

上一篇:S5PV210启动过程详解1
下一篇:S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动

推荐阅读最新更新时间:2026-03-22 11:35

s5pv210编译qt
编译tslib,执行make时提示undefined reference to `rpl_malloc' 是因为config.h.in文件中有 /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc 把#undef malloc注释掉重新make即可 requires installation of untrusted packages 一、在源里面加入软件下载地址; 二、直接用“sudo apt-get install 软件包名”这个命令安装。 在出现提示的时候按y,同意安装即可。 e
[单片机]
【ARM裸机s5pv210 】重定位操作
makefile final.bin: start.o led.o arm-linux-ld -Tlink.lds -o start.elf $^ //link.lds为链接脚本,指定链接地址 arm-linux-objcopy -O binary start.elf final.bin arm-linux-objdump -D start.elf start_elf.dis %.o : %.S arm-linux-gcc -o $@ $ -c -nostdlib %.o : %.c arm-linux-gcc -o $@ $ -c -nostdlib clean: rm *.o *
[单片机]
【ARM裸机s5pv210 】芯片初始化
#define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 #define WTCON 0xE2700000 #define SVC_STACK 0xd0037d80 .global _start _start: // 第1步:关看门狗(向WTCON的bit5写入0即可) ldr r0, =WTCON ldr r1, =0x0 str r1, // 第2步:设置SVC栈    满减栈,满的意思是入栈先移动指针再填入数据,减的意思是栈从高到低用 ldr sp, =SVC_STACK // 第3步:开/关icache
[单片机]
【ARM裸机s5pv210 】GPIO
GPJ0CON 寄存器共32位,每个引脚用4位控制,16进制的话正好一个数可以控制一个引脚 GPJ0DAT 寄存器共8位,每个引脚用1位控制,16进制的话2个数控制8个引脚 小实验测试: //Makefile文件 led.bin: led.o arm-linux-ld -Ttext 0x0 -o led.elf $^ arm-linux-objcopy -O binary led.elf led.bin %.o : %.S arm-linux-gcc -o $@ $ -c %.o : %.c arm-linux-gcc -o $@ $ -c clean: rm *.o *
[单片机]
【ARM裸机<font color='red'>s5pv210</font> 】GPIO
九鼎S5PV210开发板的SD卡启动、uboot tftp升级内核镜像
Note: 我的S5PV210板子的磁盘是emmc版本,不是nandflash版本。 1. SD卡内烧录uboot镜像,然后作为启动盘来启动emmc中的内核镜像和根文件系统。 只要破坏emmc内的uboot镜像,就可以使其从sd2启动 (因为emmc内没了完整的uboot,自然就无法启动内核) 然后使用SD卡烧录的工具软件在SD卡内烧录uboot镜像,启动盘就制作好了。 有了启动盘,就可以把uboot程序跑起来, 而uboot的作用是支持多种方式升级内核,例如tftp升级、SD卡升级,等等。 2. Uboot内使用tftp 升级内核 先设置好三个环境变量 之后在uboot内去ping PC windows主机 登录
[单片机]
九鼎<font color='red'>S5PV210</font>开发板的SD卡启动、uboot tftp升级内核镜像
S5PV210开发板 VGA测试
WY-S5PV210 V3 开发板VGA输出 设置与测试 一、修改内核使其支持VGA !-- -- 1、 !-- -- 修改Makefile 打开drivers/video/Samsung/Makefile增加 obj-$(CONFIG_FB_S3C_VGA) += s3cfb_vga.o !-- -- 2、 !-- -- 修改Kconfig 打开drivers/video/Samsung/Kconfig增加 config FB_S3C_VGA bool s3c VGA select BACKLIGHT_PWM depends on MACH_WYV210 ---help---
[单片机]
<font color='red'>S5PV210</font>开发板 VGA测试
s5pv210 uboot-2012-10移植(二) 之能够启动进入控制台
这次我们将从官网下载的最新uboot-2012-10移植到s5pv210开发板上,让其进入控制台,效果如下: 首先,我暂时没采用内核的SPL,这个将在后面给补上,这里的BL1是我自己参考资料写的,我用的是TQ210开发板,内存1G,对于不同的开发板,需要重新配置memory和修改uboot在内存里的地址,也就是CONFIG_SYS_TEXT_BASE。我的BL1代码在这里下载。 一、添加smdkv210单板 1.cp -a board/samsung/smdkc100 board/samsung/smdkv210 2.cp include/configs/smdkc100.h include/configs/smd
[单片机]
基于Linux 3.0.8 Samsung FIMC(S5PV210) 的摄像头驱动框架解读(一)
FIMC这个名字应该是从S5PC1x0開始出现的。在s5pv210里面的定义是摄像头接口。可是它相同具有图像数据颜色空间转换的作用。 而exynos4412对它的定义看起来更清楚些,摄像头接口被定义为FIMC-LITE 。颜色空间转换的硬件结构被定义为FIMC-IS。 不多说了,我们先来看看Linux3.0.8 三星的BSP包中与fimc驱动相关的文件。 上面的源代码文件组成了整个fimc的驱动框架。 通过.c文件的命名也大致能够推測到FIMC的几个用途: 1、Capture ,Camera Interface 用于控制Camera,及m2m操作 2、Output,这个用途能够简单看成:仅仅使用了FIMC的
[单片机]
基于Linux 3.0.8 Samsung FIMC(<font color='red'>S5PV210</font>) 的摄像头驱动框架解读(一)
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved