绝对干货!基于Cortex-A9,分析Linux内核I2C架构

一口Linux
关注

ARM系列文章合集如下:

《从0学arm合集》

本文基于三星Cortex-A9架构,Exynos4412讲解I2C原理、以及基于I2C的mpu6050陀螺仪的数据读取实例(包括在裸机模式下数据的读取以及基于Linux驱动的读取)。还会分析Linux内核I2C架构,篇幅过长,绝对干货。

裸机篇

本篇首先详细讲解I2C时序,然后讲解如何基于三星I2C控制实现裸机读取从设备信息方法。

前言

I2C(Inter-Integrated Circuit)总线(也称 IIC 或 I2C) 是有PHILIPS公司开发的两线式串行总线,用于连接微控制器及外围设备,是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少、控制方式简单、器件封装形式小、通信速率较高等优点。

Exynos4412 i2c控制器综述

Exynos4412精简指令集微处理器支持4个IIC总线控制器。为了能使连接在总线上的主和从设备之间传输数据,专用的数据线SDA和时钟信号线SCL被使用,他们都是双向的。

如果工作在多主机的IIC总线模式,多个4412处理器将从从机那接收数据或发送数据给从机。在IIC总线上的主机端4412会启动或终止一个数据传输。4412的IIC总线控制器会用一个标准的IIC总线仲裁机制去实现多主机和多从机传输数据。

通过控制如下寄存器以实现IIC总线上的多主机操作:

控制寄存器:                  I2CCON状态寄存器:                  I2CSTATTx/Rx数据偏移寄存器:I2CDS地址寄存器:                  I2CADD

如果I2C总线空闲,那么SCL和SDA信号线将都为高电平。在SCL为高电平期间,如果SDA有由高到低电平的跳变,那么将启动一个起始信号,如果SDA有由低到高电平的跳变,将启动一个结束信号。

主机端的设备总是提供起始和停止信号的一端。在起始信号被发出后,一个数据字节的前7位被当作地址通过SDA线被传输。这个地制值决定了总线上的主设备将要选择那个从设备作为传输对象,bit8决定传输数据的方向(是读还是写)。

I2C总线上的数据(即在SDA上传输的数据)都是以8位字节传输的,在总线上传输操作的过程中,对发送或接收的数据字节数是没有限制的。I2C总线上的主/从设备发送数据总是以一个数据的最高位开始传输(即MSB方式),传输完一个字节后,应答信号紧接其后。

Exynos4412 I2C总线接口特性共有9个通道,支持多主、从I2C总线接口。其中8个通道作为普通接口(即I2C0、I2C1....),1个通道作为HDMI的专用接口。7位地址模式。串行,8位单向或双向的数据传输。在标准模式中,每秒最多可以传输100k位,即12.5kB的数据量。在快速模式中,每秒最多可以传输400k位,即50kB的数据量。支持主机端发送、接收,从机端发送、接收操作。支持中断和查询方式。框图

从上图可以看出,4412提供4个寄存器来完成所有的IIC操作。SDA线上的数据从IICDS寄存器经过移位寄存器发出,或通过移位寄存器传入IICDS寄器;IICADD寄存器中保存4412当做从机时的地址;IICCON、IICSTAT两个寄存器用来控制或标识各种状态,比如选择工作工作模式,发出S信号、P信号,决定是否发出ACK信号,检测是否接收到ACK信号。

I2C总线接口操作

针对4412处理器的I2C总线接口,具备4种操作模式:

主机发送模式主机接收模式从机发送模式从机接收模式

下面将描述这些操作模式之间的功能关系:

0、数据有效性

SDA线上的数据必须在时钟的高电平周期保持稳定。数据线的高或低电平状态IIC位传输数据的有效性在SCL线的时钟信号是低电平才能改变。

1.  开始和停止条件

当4412的I2C接口空闲时,它往往工作在从机模式。或者说,4412的的i2c接口在SDA线上察觉到一个起始信号之前它应该工作在从机模式。当控制器改变4412的i2c接口的工作模式为主机模式后,SDA线上发起数据传输并且控制器会产生SCL时钟信号。

开始条件通过SDA线进行串行的字节传输,一个停止信号终止数据传输,停止信号是指SCL在高电平器件SDA线有从低到高电平的跳变,主机端产生起始和停止条件。当主、从设备产生一个起始信号后,I2C总线将进入忙状态。这里需要说明的是上述主从设备都有可能作为主机端。

当一个主机发送了一个起始信号后,它也应该发送一个从机地址以通知总线上的从设备。这个地址字节的低7位表示从设备地址,最高位表示传输数据的方向,即主机将要进行读还是写。当最高位是0时,它将发起一个写操作(发送操作);当最高位是1时,它将发起一个读数据的请求(接收操作)。

主机端发起一个结束信号以完成传输操作,如果主机端想在总线上继续进行数据的传输,它将发出另外一个起始信号和从设备地址。用这样的方式,它们可以用各种各样的格式进行读写操作。

下图为起始和停止信号:

2.  数据传输格式

放到SDA线上的所有字节数据的长度应该为8位,在每次传输数据时,对传输数据量没有限制。在起始信号后的第一个数据字节应该包含地址字段,当4412的I2C接口被设置为主模式时,地址字节应该由控制器端发出。在每个字节后,应该有一个应答位。

如果从机要完成一些其他功能后(例如一个内部中断服务程序)才能继续接收或发送下一个字节,从机可以拉低SCL迫使主机进入等待状态。当从机准备好接收下一个数据并释放SCL后,数据传输继续。如果主机在传输数据期间也需要完成一些其他功能(例如一个内部中断服务程序)也可以拉低SCL以占住总线。

下面的图中将说明数据传输格式:

上图中说明,在传输完每个字节数据后,都会有一个应答信号,这个应答信号在第9个时钟周期。具体过程如下(注意下面描述的读写过程都是针对 4412处理器而言,当有具体的I2C设备与4412相连时,数据表示什么需要看具体的I2C设备,4412是不知道数据的含义的):

写过程:主机发送一个起始信号S→发送从机7位地址和1位方向,方向位表示写→主机释放SDA线方便从机给回应→有从机匹配到地址,拉低SDA线作为ACK→主机重新获得SDA传输8位数据→主机释放SDA线方便从机给回应→从机收到数据拉低SDA线作为ACK告诉主机数据接收成功→主机发出停止信号。

读过程:主机发送一个起始信号S→发送从机7位地址和1位方向,方向位表示读→主机释放SDA线方便从机给回应→有从机匹配到地址,拉低SDA线作为ACK→从机继续占用SDA线,用SDA传输8位数据给主机→从机释放SDA线(拉高)方便主机给回应→主机接收到数据→主机获得SDA线控制并拉低SDA线作为ACK告诉从机数据接收成功→主机发出停止信号。

注意:在具体的I2C通信时,要看I2C设备才能确定读写时序,比如下面即将描述的第七大点中的示例,读写EEPROM中就会说道具体的数据含义,读写过程。

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存