linux gpio模拟i2c的使用



 

linux kernel 中的i2c-gpio使用

 

在linux中,我们可以自己来使用gpio来模拟i2c,但是万能的linux中其实也已经有了i2c的东东了。

 

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

static void i2c_gpio_setsda_dir(void *data, int state)
static void i2c_gpio_setsda_val(void *data, int state)
static void i2c_gpio_setscl_dir(void *data, int state)
static void i2c_gpio_setscl_val(void *data, int state)
static int i2c_gpio_getsda(void *data)
static int i2c_gpio_getscl(void *data)
 

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

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

static inline void sdalo(struct i2c_algo_bit_data *adap)
static inline void sdahi(struct i2c_algo_bit_data *adap)
static inline void scllo(struct i2c_algo_bit_data *adap)
static int sclhi(struct i2c_algo_bit_data *adap)
static void i2c_start(struct i2c_algo_bit_data *adap)
static void i2c_repstart(struct i2c_algo_bit_data *adap)
static void i2c_stop(struct i2c_algo_bit_data *adap)
static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
static int i2c_inb(struct i2c_adapter *i2c_adap)
static int test_bus(struct i2c_algo_bit_data *adap, char *name)
static int try_address(struct i2c_adapter *i2c_adap,
                          unsigned char addr, int retries)
static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int bit_xfer(struct i2c_adapter *i2c_adap,
                       struct i2c_msg msgs[], int num)
/* -----exported algorithm data: -------------------------------------   */
 
static const struct i2c_algorithm i2c_bit_algo = {
         .master_xfer    = bit_xfer,
         .functionality   = bit_func,
};


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

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

 

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

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

static struct i2c_gpio_platform_data i2c_bus_data = {
 .sda_pin = GPIO103,
 .scl_pin = GPIO102,
 .udelay  = 20,
 .timeout = 100,
 .sda_is_open_drain = 1,
 .scl_is_open_drain = 1,
};
static struct platform_device arch_device_i2c[] = {
    {
    .name              = "arch-i2c-1",
        .id            = 0,
    .num_resources = ARRAY_SIZE(arch_resource),
    .resource      = arch_resource,
    },
    {
    .name              = "arch-i2c-2",
        .id            = 1,
    .num_resources = ARRAY_SIZE(arch_resource),
    .resource      = arch_resource,
    },
//add
{
    .name              = "i2c-gpio",
        .id            = 2,
    .dev              =
                    {
                             .platform_data = &i2c_bus_data,
                    }
    },
//end add
};


 

 

 

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

 

2、  在使用gpio模拟i2c的设备中,需要指定使用的i2c的id,这样才可以知道使用的哪一个。这样在初始化时会对所在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调试的时候,也要具体再读读代码看看和你的时序是否一致,切记。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
i2c-gpio是一个在Linux内核中实现的I2C总线驱动程序,它使用GPIO引脚模拟I2C总线的功能。通过i2c-gpio,您可以在不具备硬件I2C总线的系统上使用软件模拟的I2C通信。 要使用i2c-gpio驱动程序,您需要进行以下步骤: 1. 确保内核配置中启用了i2c-gpio驱动程序。您可以通过查看内核配置文件(通常位于`/usr/src/linux/.config`)或通过内核配置工具(如make menuconfig)来检查。 2. 确保所需的GPIO引脚已正确配置为用于I2C通信。这通常涉及到在设备树或板级文件中进行配置。具体的配置方法取决于您所使用的硬件平台和内核版本。 3. 加载i2c-gpio模块。您可以使用`modprobe`命令来加载模块,例如: ``` modprobe i2c-gpio ``` 4. 配置i2c-gpio驱动程序的参数。您可以通过在/sys/class/i2c-gpio目录下的相应GPIO设备目录中设置参数文件来配置,例如: ``` echo "gpio=<SDA_GPIO_PIN>,<SCL_GPIO_PIN>" > /sys/class/i2c-gpio/<I2C_ADAPTER>/new_device ``` 其中,`<SDA_GPIO_PIN>`和`<SCL_GPIO_PIN>`分别是用于数据线(SDA)和时钟线(SCL)的GPIO引脚号,`<I2C_ADAPTER>`是i2c-gpio适配器的编号。 5. 完成上述步骤后,您应该能够在`/dev`目录下看到相应的I2C设备节点,例如`/dev/i2c-X`,其中X是适配器编号。 现在,您可以使用标准的I2C工具(如i2c-tools)或编写自己的应用程序来与通过i2c-gpio驱动程序模拟的I2C设备进行通信。 请注意,i2c-gpio是一种软件模拟的解决方案,在某些情况下可能会受到性能或兼容性方面的限制。因此,如果您的系统有硬件I2C总线可用,最好使用硬件解决方案来获得更好的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值