Tinkerboard2/i2c

From wiki
Jump to: navigation, search


前言

ROCKCHIP系列芯片为客户提供了标准I2C 总线,方便客户实现对不同外接 设备的控制和访问。I2C总线控制器通过串行数据(SDA)线和串行时钟 (SCL)线在连接到总线的器件间传递信息。每个器件都有一个唯一的地址识别 (无论是微控制器——MCU、LCD 驱动器、存储器或键盘接口),而且都可以作 为一个发送器或接收器(由器件的功能决定)。 Rockchip I2C 控制器支持下列 功能︰ 兼容 I2C 与 SMBus 总线 仅支持主模式下的 I2C 总线 软件可编程时钟频率支持到400kbps,部分芯片可高达 1000kbps 支持 7 位和 10 位寻址模式 一次中断或轮询至多32个字节的数据传输 I2C 的流程在两个驱动上大致是一样,写是单纯的 TX 模式 (I2C_CON[1:0]=2’b00),而读一般使用TRX 模式(I2C_CON[1:0]=2’b01)。下面的 I2C 控制器操作流程图是描述软件如何通过这个 I2C 控制器寄存器来配置和执行 I2C 任务。描述分为3部分,传输模式,混合模式和接收模式。 I2C 的参数配置最主要就是 I2C 频率的配置,可配 I2C frequency 除了与芯片有 关外,主要是由 I2C SCL rise time 决定的,因为 I2C 协议标准里面对上升沿和 下降沿时间有规定要求特别是上升沿时间,如果超过了协议规定的最大值,则 I2C 通讯可能失败,下面是协议里面规定的最大最小值范围,下图表示了二者之 I2C 的驱动 i2c-rk3x.c 与 i2c-rockchip.c 两个配置方式是不一样的,区别如下:

简述I2C的linux驱动
I2C在linux内核层的驱动框架主要由三部分组成:
I2C核心层:

​ I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(algorithm)的上层部分,并且还提供了一系列与具体硬件平台无关的接口函数以及探测设备,检测设备地址的上层代码等。它位于内核源码目录下的drivers/i2c/i2c-core.c文件中,是I2C总线驱

动和设备驱动之间依赖于I2C核心作为纽带。

​ I2C核心中的主要函数包括:

​ 增加/删除i2c_adapter

int i2c_add_adapter(struct i2c_adapter *adap);
int i2c_del_adapter(struct i2c_adapter *adap);
增加/删除i2c_driver
int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
int i2c_del_driver(struct i2c_driver *driver);
inline int i2c_add_driver(struct i2c_driver *driver);
​ i2c_client依附/脱离
int i2c_attach_client(struct i2c_client *client);
int i2c_detach_client(struct i2c_client *client);
i2c传输、发送和接收
int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num);
 用于进行I2C适配器和I2C设备之间的一组消息交互。其本身不具备驱动适配器物理硬件完成消息交互的能力,它只是寻找到i2c_adapter对应的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正驱动硬件流程。
int i2c_master_send(struct i2c_client *client,const char *buf ,int count);
int i2c_master_recv(struct i2c_client *client, char *buf ,int count);
​ i2c_master_send()和i2c_master_recv()函数内部会调用i2c_transfer()函数分别完成一条写消息和一条读消息。
I2C控制命令分派

​ 下面函数有助于将发给I2C适配器设备文件ioctl的命令分派给对应适配器的algorithm的algo_control()函数或i2c_driver的command()函数:

int i2c_control(struct i2c_client *client, unsigned int cmd, unsigned long arg);
void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg);
I2C总线驱动层:

​ I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。

​ 它主要完成的功能有:

a) 初始化I2C适配器所使用的硬件资源,申请I/O地址、中断号等。

b) 通过i2c_add_adapter()添加i2c_adapter的数据结构,当然这个i2c_adapter数据结构的成员已经被xxx适配器的相应函数指针所初始化。

c) 释放I2C适配器所使用的硬件资源,释放I/O地址、中断号等。

d) 通过i2c_del_adapter()删除i2c_adapter的数据结构。 I2C总线驱动层: ​ I2C设备驱动(也称为客户驱动)是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。I2C设备驱动模块加载函数通用的方法是在I2C设备驱动模块加载函数中完成两件事:通过register_chrdev()函数将I2C设备注册为一个字符设备。通过I2C核心的i2c_add_driver()函数添加i2c_driver。

如何使用I2C tools测试I2C外设 I2C tools概述: ​ I2C tools包含一套用于Linux应用层测试各种各样I2C功能的工具。它的主要功能包括:总线探测工具、SMBus访问帮助程序、EEPROM解码脚本、EEPROM编程工具和用于SMBus访问的python模块。只要你所使用的内核中包含I2C设备驱动,那么就可以在你的板子中正常使用这个测试工具。 下载I2C tools源码: ​ 前面我们已经说过了这个I2C tools工具是开源的,那么这个源码在哪里可以找到呢?

​ 下载方法一:直接在内核的网站https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/下载I2C tools代码的压缩包。

​ 下载方法二:利用git管理工具下载这个I2C tools的源代码,命令为git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git强烈建议读者采用第二种方法下载这个代码,因为你可以通过git快速地了解这个开源代码的不同版本的功能改进及bug修复,而且使用git开发也是作为一名优秀的开发人员必备的一项技能。 编译I2C tools源码: ​ 进入刚才利用git下载好的iic-tools源码目录,修改编译工具为你当前使用的交叉编译工具:

CC ?= arm-linux-gnueabihf-gcc
 AR ?= arm-linux-gnueabihf-ar

编译源码:如果你想编译静态版本,你可以输入命令:make USE_STATIC_LIB=1;如果使用动态库的话,可以直接输入make进行编译。安装命令为:make install,如果你想要让最后生成的二进制文件最小的话,可以在“make install”之前运行“make strip”。但是,这将不能生成任何调试库,也就不能尝试进一步调试。然后将tools目录下的5个可执行文件i2cdetect,i2cdump,i2cget,i2cset和i2ctransfer复制到板子的/usr/sbin/中;将lib目录下的libi2c.so.0.1.1文件复制到板子的/usr/lib/libi2c.so.0。之后别忘了将上面的文件修改为可执行的权限。 介绍I2C tools各功能之—i2cdetect ​ i2cdetect的主要功能就是I2C设备查询,它用于扫描I2C总线上的设备。它输出一个表,其中包含指定总线上检测到的设备的列表。

​ 该命令的常用格式为:i2cdetect [-y] [-a] [-q|-r] i2cbus [first last]。具体参数的含义如下:

该功能的常用方式:

​ 第一,先通过i2cdetect -l查看当前系统中的I2C的总线情况:

第二,若总线上挂载I2C从设备,可通过i2cdetect扫描某个I2C总线上的所有设备。可通过控制台输入i2cdetect -y 1:(其中"–"表示地址被探测到了,但没有芯片应答; "UU"因为这个地址目前正在被一个驱动程序使用,探测被省略;而16进制的地址号60,1e和50则表示发现了一个外部片选从地址为0x60,0x1e(AP3216)和0x50(eeprom)的外设芯片。

第三,查询I2C总线1 (I2C -1)的功能,命令为i2cdetect -F 1: