I2c子系统
I2c协议
I2C总线是一个标准的双向接口,它使用一个控制器(称为主控制器)与从设备进行通信。 从机不能传送数据,除非它已被主机寻址。 I2C总线上的每个设备都有一个特定的设备地址,以区分同一I2C总线上的其他设备。I2c有两根线,一根时钟线,一根数据线。I2c是msb,高电平采样。I2C总线以启动信号START来掌管总线,以停止信号STOP来释放总线;启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R/W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号。
每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。I2C 总线内部使用漏极开路输出驱动器,因此 SDA和 SCL 可以被拉低为低电平,但是不能被驱动为高电平,所以每条线上都要使用一个上拉电阻,默认情况下将其保持在高电平。
启动条件:当SCL是高电平时,SDA从高电平向低电平切换。停止条件:当SCL是高电平时,SDA由低电平向高电平切换。
读/写位:一位,如果主机是向从机发送数据则为低电平,请求数据则为高电平。ACK/NACK:消息中的每个帧后均带有一个ACK/NACK位。如果成功接收到地址帧或数据帧,接收设备会返回一个ACK位用于表示确认。
寻址:主机将要通信的从机地址发送给每个从机,然后每个从机将其与自己的地址进行比较。如果地址匹配,它将向主机发送一个低电平ACK位。如果不匹配,则不执行任何操作,SDA线保持高电平。
读/写位:地址帧的末尾包含一个读/写位。如果主机要向从机发送数据,则为低电平。如果是主机向从机请求数据,则为高电平。
数据帧:当主机检测到从机的ACK位后,就可以发送第一个数据帧了。数据帧始终为8位,每个数据帧后紧跟一个ACK / NACK位,来验证接收状态。当发送完所有数据帧后,主机可以向从机发送停止条件来终止通信。
设备树与I2C子系统
compatible:设备兼容属性,用于与设备绑定;
reg:表明i2c控制器的基地址以及地址长度;
interrupt:表明控制器使用的中断资源;
pinctrl-name:定义设备的状态(休眠、唤醒等);
pinctrl-0/1/2:使用一组pin对应pinctrl-name定义的状态;
clock:使用的时钟源;
clock-frequency:i2c通信速率
dma:表明控制器使用的dma控制器资源;
status:控制器状态
设备树与驱动
simple-bus下面的子节点会被解析成一个platform-device然后注册到platform-bus中,控制器驱动会被当成一个platform-driver注册到platform-bus中,然后通过compatible属性匹配上了之后,进入到对应的probe函数中,实现控制器的初始化。在i2c控制器的子节点也会被解析成一个device注册到i2c_bus中,等待对应的drive匹配。
Linux的i2c子系统框架分析