i.MX RT1010的I2C Slave时钟延展功能小记

cathy的头像
cathy 发布于:周四, 12/02/2021 - 15:05 ,关键词:

最近客户在使用i.MX RT1010的I2C作为从机设备与主机通讯,使用了时钟延展的功能(clock stretching)。在开发过程中遇到了一些小烦恼和小细节,在此呢,也写下一篇文档予以总结。

什么是时钟延展

首先,简单介绍一下什么是时钟延展。时钟延展是指从机通过将SCL拉低以暂停数据传输的一个过程,在暂停过程中,从机可以有更多的时间处理接收到的数据,或者准备即将发送的数据。在相关的处理和准备完成之后,将交出SCL的控制权,主机继续控制SCL的节奏进行数据的收发。换句话说,时钟延展是从机跟不上主机的速度,让老司机等等它,啊不,是让主机等等它的操作。

时钟延展通常分为两种,一种是字节级(byte)的时钟延展,一种是比特级(bit)的时钟延展。字节级的时钟延展是按照字节为单位开展,每一个字节收发结束之后启动。比特级则是每个数据bit都进行延展,强行让master慢下来。

在查阅相关资料的过程中发现,并不是所有的I2C从机设备都支持时钟延展,例如I2C的传感器,部分存储设备;也并不是所有的主机设备也支持时钟延展,例如使用IO口模拟实现的I2C或者是FPGA上实现的I2C。因此在使用之前,需要检查器件自身是否支持时钟延展。

四种时钟延展功能

在我们i.MX RT1010上总共支持4种字节级的时钟延展:

“i.MX

下面我们将对这四种时钟延展的功能进行简要介绍,以下介绍均为从机视角。

延展功能1:收完地址等一等

在从机接收完主机发送的地址信息后,且AVF 置位,则此时从机获得SCL的控制权,开始持续拉低SCL开启时钟延展。那么什么时候结束呢,从硬件状态机的角度看,当AVF bit被清除,时钟延展结束,主机获得SCL的控制权。

举个例子,用我们SDK工程在接收到地址信息后强行延时500us再去清除AVF bit, 看看波形是怎样的:

“i.MX

从图中可以看到,两次时钟间隔约491us,基本上与500us的预期相匹配。并不是完美的500us的原因是,延时函数没有使用定时器精确延时。

延展功能2:发送之前等一等

在从机接收到主机的地址信息和读指令后,TDF将会置位,则此时从机获得SCL的控制权。同样是在清除TDF bit之后,主机再次获得SCL的控制权。在这个过程中,从机可以根据主机发送的信息,把要发送的数据准备好,再释放SCL的控制权。同样举个例子,再清除TDF bit 之前等一等,这次等的长一点800us。

“i.MX

延展功能3:接收之前等一等

在从机接收到数据之后,RDF会置位,此时从机会获得SCL的控制权。同样是在清除TDF bit之后,主机再次获得SCL的控制权。拉个波形看看,在清标志位前拉个1000us的延时,波形如下图所示。

“i.MX

延展功能4:手动回ACK

这里是指,当主机把数据(地址信息或者数据信息)发送给从机后,在传送完第八个bit(或者说是第八个时钟)之后,从机即获得了SCL的控制权限,在此时需要手动向STAR寄存器中最后一位写0或者1,以向主机反馈ACK 或者NACK。在写0之前,我们增加一个500us的延时,地址信息的波形见下图,可以看到第八个和第九个CLK时钟的间隔被拉长。

“i.MX

从机接收数据的信息见下图,同样可以看到,第八个和第九个的时钟被拉长了。

“i.MX

时钟延展的时序要求

在使用时钟延展的功能后,同样不能忽略的一个要点是要满足I2C的AC timing,即数据的建立时间和保持时间。对于不同的工作速度,I2C对于这两个参数的时间要求也是不同的,下图为I2C的规范上的截图。

“i.MX

对于i.MX RT1010来说,我们在开启时钟延展功能后需要对下面的两个参数进行设置,以满足I2C的timing要求。

CLKHOLD: I2C的数据的建立时间,需要根据不同的通讯速度进行设置。

DATAVD: I2C的数据保持时间,通常来看保持为0即可。

“i.MX

如果不能正确设置CLKHOLD的时间会怎样呢?

造成时序混乱,当SCL的驱动能力较强,且SDA的负载较重的时候,甚至会引起SCL上升的比SDA速度快,那么想一下I2C的停止条件,当SCL处于高电平时,SDA拉高。那么就会让总线停止传输,除此以外,可能还会有其他的未知问题发生。

其次,关于CLKHOLD时间的计算,目前的驱动程序是有些小问题的。因此建议徒手撸寄存器,自己把想要的数值填写到CLKHOLD寄存器内。对于具体的时间,计算公式如下:

t =(CLKHOLD + 3) * Tclk

这里的Tclk是指I2C的functional clock的周期。因此,真正的建立时间,是CLKHOLD的数值和I2C 的输入时钟频率共同作用的结果。

哦对了,如何使能时钟延展功能?

如果你喜欢寄存器操作,那么可以在SCFGR1寄存器中的bit[3:0]直接开启对应的功能:

“i.MX

如果你习惯SDK操作,那么在这个结构体里把对应的功能写true吧:

“i.MX

来源:恩智浦MCU加油站
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 111