linux gpio模拟i2c的使用/用GPIO模拟I2C总线-1

转载 2013年12月02日 16:00:16
linux中,我们可以自己来使用gpio来模拟i2c,但是万能的linux中其实也已经有了i2c的东东了。

 

现在看看i2c-gpio.c文件中到底提供了哪些接口

  1. static void i2c_gpio_setsda_dir(void *data, int state)  
  2. static void i2c_gpio_setsda_val(void *data, int state)  
  3. static void i2c_gpio_setscl_dir(void *data, int state)  
  4. static void i2c_gpio_setscl_val(void *data, int state)  
  5. static int i2c_gpio_getsda(void *data)  
  6. static int i2c_gpio_getscl(void *data)  
 

一看上面的接口,相当明确,跟普通的gpio模拟i2c所实现的接口一致,是实现的gpiosdascl的设置,仅此而已。

kernel/driver/i2c/algos/i2c-algo-bit.c中是系统中默认提供的gpio模拟i2c的框架代码。

 

  1. static inline void sdalo(struct i2c_algo_bit_data *adap)  
  2. static inline void sdahi(struct i2c_algo_bit_data *adap)  
  3. static inline void scllo(struct i2c_algo_bit_data *adap)  
  4. static int sclhi(struct i2c_algo_bit_data *adap)  
  5. static void i2c_start(struct i2c_algo_bit_data *adap)  
  6. static void i2c_repstart(struct i2c_algo_bit_data *adap)  
  7. static void i2c_stop(struct i2c_algo_bit_data *adap)  
  8. static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)  
  9. static int i2c_inb(struct i2c_adapter *i2c_adap)  
  10. static int test_bus(struct i2c_algo_bit_data *adap, char *name)  
  11. static int try_address(struct i2c_adapter *i2c_adap,  
  12.                           unsigned char addr, int retries)  
  13. static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
  14. static int acknak(struct i2c_adapter *i2c_adap, int is_ack)  
  15. static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
  16. static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)  
  17. static int bit_xfer(struct i2c_adapter *i2c_adap,  
  18.                        struct i2c_msg msgs[], int num)  
  19. /* -----exported algorithm data: -------------------------------------   */  
  20.    
  21. static const struct i2c_algorithm i2c_bit_algo = {  
  22.          .master_xfer    = bit_xfer,  
  23.          .functionality   = bit_func,  
  24. };  
 

 

这里对于任何一个做过gpio模拟i2c模拟的童鞋来说都没有陌生的东西,不明白的可以看看i2c的协议,比我说的清楚。

这里说下出现的struct i2c_algorithm,其中的master_xfer就是我们调用i2c_master_send/i2c_master_recv的时候最终调用的接口。

 

下面说说如何使用此i2c-gpio的框架代码

1、  查看board.c文件,先看看系统中的i2c的注册是在哪里注册的,添加如下

[c-sharp] view plaincopy
  1. static struct i2c_gpio_platform_data i2c_bus_data = {  
  2.  .sda_pin = GPIO103,  
  3.  .scl_pin = GPIO102,  
  4.  .udelay  = 20,  
  5.  .timeout = 100,  
  6.  .sda_is_open_drain = 1,  
  7.  .scl_is_open_drain = 1,  
  8. };  
  9. static struct platform_device arch_device_i2c[] = {  
  10.     {  
  11.     .name              = "arch-i2c-1",  
  12.         .id            = 0,  
  13.     .num_resources = ARRAY_SIZE(arch_resource),  
  14.     .resource      = arch_resource,  
  15.     },  
  16.     {  
  17.     .name              = "arch-i2c-2",  
  18.         .id            = 1,  
  19.     .num_resources = ARRAY_SIZE(arch_resource),  
  20.     .resource      = arch_resource,  
  21.     },  
  22. //add  
  23. {  
  24.     .name              = "i2c-gpio",  
  25.         .id            = 2,  
  26.     .dev              =  
  27.                     {  
  28.                              .platform_data = &i2c_bus_data,  
  29.                     }  
  30.     },  
  31. //end add  
  32. };  
 

 

 

这里看到了系统中有了两个i2c了,这里platform_device注册的时候id则使用了2,device name则是和i2c gpiodriver中的name是一致的,即i2c-gpio.c中的name

 

2、  在使用gpio模拟i2c的设备中,需要指定使用的i2cid,这样才可以知道使用的哪一个。这样在初始化时会对所在i2c总线进行遍历并得到该设备的适配器等信息,这样就像使用普通的i2c那样来使用了。

 

-----------------------------------------------华丽的分割线----------------------------------------------------------------------------

 

直接用GPIO口模拟I2C时序和利用内核模块i2c-gpio虚拟i2c总线的区别:

 

1. 用GPIO口模拟I2C时序不需要在系统启动时注册I2C总线,只需要在I2C设备驱动中单独实现。用i2c-gpio模块虚拟i2c总线需要在系统启动时注册新的I2C总线,并将i2c设备挂载到新的i2c总线,涉及的范围较广。

 

2. 用GPIO口模拟I2C时序,代码操作较繁琐,且不方便挂载多个i2c设备。用i2c-gpio模块可以完全模拟i2c总线,可以挂载多个设备。

 

3. 在i2c读写操作时,用GPIO口模拟I2C时序需要每次根据读/写操作发送器件地址<<1+1/0,然后再发送寄存器地址。用i2c-gpio模块相当于直接在i2c总线上操作,在系统启动挂载i2c设备时已经告诉了i2c总线它的地址,在该设备自己的驱动中,只需要通过i2c_add_driver操作即可以得到其地址等诸多信息,读写操作只需要发送寄存器地址即可。

 

Ps

   I2c调试的时候,也要具体再读读代码看看和你的时序是否一致,切记。

使用GPIO模拟I2C总线进行通信

下面给出了模拟I2C总线进行读写的伪代码,用以说明如何使用GPIO实现I2C通信: #define SDA 254                         //定义SDA所对应的GPIO接口编...

使用GPIO模拟I2C总线进行通信

I2C总线的通信过程(见图4-8)主要包含三个主要阶段:起始阶段、数据传输阶段和终止阶段。 1. 起始阶段 在I2C总线不工作的情况下,SDA(数据线)和SCL(时钟线)上的信号均为高...

使用GPIO口模拟I2C总线并挂载设备

……

使用GPIO口模拟I2C总线并挂载设备

前言:  在许多情况下,我们并没有足够的I2C总线,本文主在介绍如何利用Linux内核中的i2c-gpio模块,利用2条GPIO线模拟i2c总线,并挂载设备。  思路:  先通过对i2c-gpio所定...
  • nic_r
  • nic_r
  • 2012年03月23日 17:06
  • 2399

使用GPIO模拟I2C总线进行通信

 I2C总线的通信过程(见图4-8)主要包含三个主要阶段:起始阶段、数据传输阶段和终止阶段。 1. 起始阶段 在I2C总线不工作的情况下,SDA(数据线)和SCL(时钟线)上的信...

gpio 模拟i2c总线

  • 2017年05月26日 15:30
  • 7KB
  • 下载

GPIO模拟类I2C总线基础函数实例

我们先了解一下I2C总线基础知识. I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。是微电子通信控制领域广...

linux gpio模拟i2c的使用

 linux kernel 中的i2c-gpio使用 在linux中,我们可以自己来使用gpio来模拟i2c,但是万能的linux中其实也已经有了i2c的东东了。 现在看看i2c-gpio.c文件中到...

linux gpio模拟i2c的使用

http://blog.csdn.net/skywalkzf/article/details/6575773 linux kernel 中的i2c-gpio使用   在linux中,我们可以自己...

linux gpio模拟i2c的使用

linux kernel 中的i2c-gpio使用   在linux中,我们可以自己来使用gpio来模拟i2c,但是万能的linux中其实也已经有了i2c的东东了。   现在看看i2c-gpio.c...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux gpio模拟i2c的使用/用GPIO模拟I2C总线-1
举报原因:
原因补充:

(最多只允许输入30个字)