我的RTOS|我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)
非常久没有关注RTOS了,所以也一直没有更新。近期闲了,把GPIO I2C调通了。简单移植了Touch。在S5PV210上使用。
【我的RTOS|我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)】调试I2C时。废了非常多周折,最后借助示波器才发现一个小小的错误。折腾了非常久非常久。
简要说下步骤:
1、首先I2C驱动,使用GPIO I2C的方式
#include
#include #define DELAY10#define SDA 0
#define SCL 1#defineGPD1CON(*(volatile unsigned long *) 0xE02000C0)
#defineGPD1DAT(*(volatile unsigned long *) 0xE02000C4)
#defineGPD1PUD(*(volatile unsigned long *) 0xE02000C8)
#defineGPD1DRV(*(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 = https://www.it610.com/article/((send_byte & out_mask) ?
1 : 0); if (value =https://www.it610.com/article/= 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 = https://www.it610.com/article/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
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("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固件信息。就说明i2c通信正常了。
3、看下效果^^
文章图片
文章图片
文章图片
最后两张的动画比較卡。
4:、存在问题及缺点
因为是电容屏,中断出发,触摸的时候。会不停的上报中断,会导致其它线程block。发生卡顿的情况,尤其画面比較复杂的时候。后期能够採取查询的方法,放在单独的线程其中或者减少touch的报点率;
另外就是lcd仅仅有一层framebuffer,多层显示倒是ucgui的效率低下,后期优化能够同一时候打开至少两个framebuffer。
5、源代码
http://download.csdn.net/detail/liujia2100/8859911
后期尝试移植lwip,搭配arduino。物联网^^.
推荐阅读
- 一个小故事,我的思考。
- 家乡的那条小河
- 前任
- 绘本讲师训练营【18期】14/21《我的情绪小怪兽》故事会新体验
- 我的友谊纪念日
- 从我的第一张健身卡谈传统健身房
- 阴雨
- 多想你明白我的心意
- 我的世界同人小说《暮色齿轮》第三回|我的世界同人小说《暮色齿轮》第三回 回忆
- 【变化】我的青椒学习之旅