概述
功能简介
I3C(Improved Inter Integrated Circuit)总线是由MIPI Alliance开发的一种简单、低成本的双向二线制同步串行总线。
I3C是两线双向串行总线,针对多个传感器从设备进行了优化,并且一次只能由一个I3C主设备控制。相比于I2C,I3C总线拥有更高的速度、更低的功耗,支持带内中断、从设备热接入以及切换当前主设备,同时向后兼容I2C从设备。I3C增加了带内中断(In-Bind Interrupt)功能,支持I3C设备进行热接入操作,弥补了I2C总线需要额外增加中断线来完成中断的不足。I3C总线上允许同时存在I2C设备、I3C从设备和I3C次级主设备。
基本概念
- IBI(In-Band Interrupt):带内中断。
在SCL线没有启动信号时,I3C从设备可以通过拉低SDA线使主设备发出SCL启动信号,从而发出带内中断请求。若有多个从设备同时发出中断请求,I3C主设备则通过从设备地址进行仲裁,低地址优先相应。
- DAA(Dynamic Address Assignment):动态地址分配。
I3C支持对从设备地址进行动态分配从而避免地址冲突。在分配动态地址之前,连接到I3C总线上的每个I3C/I2C设备都应以两种方式之一来唯一标识:
-
设备可能有一个符合I2C规范的静态地址,主机可以使用此静态地址。
-
在任何情况下,I3C设备均应具有48位的临时ID。除非设备具有静态地址且主机使用静态地址,否则主机应使用此48位临时ID。
-
CCC(Common Command Code):通用命令代码。
所有I3C设备均支持CCC,可以直接将其传输到特定的I3C从设备,也可以同时传输到所有I3C从设备。
- BCR(Bus Characteristic Register):总线特性寄存器。
每个连接到I3C总线的I3C设备都应具有相关的只读总线特性寄存器(BCR),该寄存器描述了I3C兼容设备在动态地址分配和通用命令代码中的作用和功能。
- DCR(Device Characteristic Register):设备特性寄存器。
连接到I3C总线的每个I3C设备都应具有相关的只读设备特性寄存器(DCR),该寄存器描述了用于动态地址分配和通用命令代码的I3C兼容设备类型(例如加速度计、陀螺仪等)。
运作机制
在HDF框架中,同类型控制器对象较多时(可能同时存在十几个同类型控制器),如果采用独立服务模式则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。I3C模块采用统一服务模式(如图1)。
I3C模块各分层的作用为:
-
接口层:提供打开设备,写入数据,关闭设备的能力。
-
核心层:主要负责服务绑定、初始化以及释放管理器,并提供添加、删除以及获取控制器的能力。由于框架需要统一管理I3C总线上挂载的所有设备,因此还提供了添加、删除以及获取设备的能力,以及中断回调函数。
-
适配层:由驱动适配者实现与硬件相关的具体功能,如控制器的初始化等。
在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。
图 1 I3C统一服务模式结构图
约束与限制
I3C模块当前仅支持轻量和小型系统内核(LiteOS-A) 。
开发指导
场景介绍
I3C可连接单个或多个I3C、I2C从器件,它主要用于:
-
与传感器通信,如陀螺仪、气压计或支持I3C协议的图像传感器等。
-
通过软件或硬件协议转换,与其他通信接口(如UART串口等)的设备进行通信。
当驱动开发者需要将I3C设备适配到OpenHarmony时,需要进行I3C驱动适配,下文将介绍如何进行I3C驱动适配。
接口说明
为了保证上层在调用I3C接口时能够正确的操作硬件,核心层在//drivers/hdf_core/framework/support/platform/include/i3c/i3c_core.h中定义了以下钩子函数。驱动适配者需要在适配层实现这些函数的具体功能,并与这些钩子函数挂接,从而完成接口层与核心层的交互。
I3cMethod定义:
struct I3cMethod {
int32_t (*sendCccCmd)(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc);
int32_t (*transfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);
int32_t (*i2cTransfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);
int32_t (*setConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);
int32_t (*getConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);
int32_t (*requestIbi)(struct I3cDevice *dev);
void (*freeIbi)(struct I3cDevice *dev);
};
c
表 1 I3cMethod结构体成员的钩子函数功能说明
函数成员 | 入参 | 出参 | 返回值 | 功能 |
---|---|---|---|---|
sendCccCmd | cntlr:结构体指针,核心层I3C控制器 ccc:传入的通用命令代码结构体指针 |
ccc:传出的通用命令代码结构体指针 | HDF_STATUS相关状态 | 发送CCC(Common command Code,即通用命令代码) |
Transfer | cntlr:结构体指针,核心层I3C控制器 msgs:结构体指针,用户消息 count:int16_t,消息数量 |
msgs:结构体指针,用户消息 | HDF_STATUS相关状态 | 使用I3C模式传递用户消息 |
i2cTransfer | cntlr:结构体指针,核心层I3C控制器 msgs:结构体指针,用户消息 count:int16_t,消息数量 |
msgs:结构体指针,用户消息 | HDF_STATUS相关状态 | 使用I2C模式传递用户消息 |
setConfig | cntlr:结构体指针,核心层I3C控制器 config:控制器配置参数 |
无 | HDF_STATUS相关状态 | 设置I3C控制器配置参数 |
getConfig | cntlr:结构体指针,核心层I3C控制器 | config:控制器配置参数 | HDF_STATUS相关状态 | 获取I3C控制器配置参数 |
requestIbi | device:结构体指针,核心层I3C设备 | 无 | HDF_STATUS相关状态 | 为I3C设备请求IBI(In-Bind Interrupt,即带内中断) |
f |