非常久没有关注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_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; } Touch IC为 FT5406, slave地址为0x70. 借助博友的一页芯片资料,写了最简单的单点读取: 多点也非常easy。能够參考android 多点触控协议上报点 3、看下效果^^ 最后两张的动画比較卡。 4:、存在问题及缺点 因为是电容屏,中断出发,触摸的时候。会不停的上报中断,会导致其它线程block。发生卡顿的情况,尤其画面比較复杂的时候。后期能够採取查询的方法,放在单独的线程其中或者减少touch的报点率; 另外就是lcd仅仅有一层framebuffer,多层显示倒是ucgui的效率低下,后期优化能够同一时候打开至少两个framebuffer。 5、源代码 http://download.csdn.net/detail/liujia2100/8859911
2、Touch驱动
#include
在touch_init 初始化中可以取到touch固件信息。就说明i2c通信正常了。



上一篇:S5PV210启动过程详解1
下一篇:S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
推荐阅读最新更新时间:2026-03-22 11:35
- RDR-142 - 35W电源
- i.MX RT1060 Evaluation Kit
- 使用 Embedded Planet 的 5CEFA9U27 的参考设计
- DC1369A-D、LTC2258-14 演示板、14 位 65 Msps ADC、LVDS 输出、5-170MHz
- LT3990EMSE-5 12V 降压转换器的典型应用
- 使用 Analog Devices 的 LTC1148 的参考设计
- LT1377IS8 具有直接反馈的正负转换器的典型应用
- 使用 NXP Semiconductors 的 TL431AI 的参考设计
- LT8304IS8E 18V 至 80Vin、5Vout 隔离反激式转换器的典型应用电路
- LT3512EMS 演示板,单片式高压隔离反激式转换器 36V VIN 75V,VOUT = 5V @ 500mA

Azure RTOS ThreadX内核用户手册,含SMP多核(中文版)
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号