4. RK I2C 控制器硬件特性
瑞芯微 RK 系列 SoC 内部集成了多个 I2C 控制器(I2C0 ~ I2C8),每个控制器都是一个独立的主机控制器,支持标准模式(100 Kbps)、快速模式(400 Kbps)和高速模式(3.4 Mbps)。本章深入剖析 RK I2C 控制器的寄存器模型、FIFO 机制、DMA 支持以及时钟频率配置,为后续驱动开发打下坚实的硬件基础。
4.1 寄存器描述
RK I2C 控制器基于 Synopsys DesignWare APB I2C 核,寄存器地址空间为 0x1000(4KB)。核心寄存器分为控制类、状态类、数据类与 DMA 类四组。下表列出驱动开发中最常访问的寄存器:
| 偏移地址 | 寄存器名称 | 宽度 | 功能描述 |
|---|---|---|---|
| 0x00 | IC_CON | 32 | 控制寄存器:主/从模式、地址模式(7/10位)、速度模式选择 |
| 0x04 | IC_TAR | 32 | 目标地址寄存器:设置从设备地址 |
| 0x08 | IC_SAR | 32 | 自身地址寄存器(从模式使用) |
| 0x10 | IC_DATA_CMD | 32 | 数据命令寄存器:读写数据与命令写入 |
| 0x14 | IC_SS_SCL_HCNT | 32 | 标准模式 SCL 高电平计数 |
| 0x18 | IC_SS_SCL_LCNT | 32 | 标准模式 SCL 低电平计数 |
| 0x1C | IC_FS_SCL_HCNT | 32 | 快速模式 SCL 高电平计数 |
| 0x20 | IC_FS_SCL_LCNT | 32 | 快速模式 SCL 低电平计数 |
| 0x24 | IC_HS_SCL_HCNT | 32 | 高速模式 SCL 高电平计数 |
| 0x28 | IC_HS_SCL_LCNT | 32 | 高速模式 SCL 低电平计数 |
| 0x2C | IC_INTR_STAT | 32 | 中断状态寄存器 |
| 0x30 | IC_INTR_MASK | 32 | 中断掩码寄存器 |
| 0x34 | IC_RAW_INTR_STAT | 32 | 原始中断状态寄存器(不受掩码影响) |
| 0x38 | IC_RX_TL | 32 | 接收 FIFO 阈值 |
| 0x3C | IC_TX_TL | 32 | 发送 FIFO 阈值 |
| 0x40 | IC_CLR_INTR | 32 | 清除中断寄存器(写任意值清除) |
| 0x44 | IC_ENABLE | 32 | 控制器使能寄存器 |
| 0x48 | IC_STATUS | 32 | 状态寄存器:FIFO 空/满、总线活动等 |
| 0x4C | IC_TXFLR | 32 | 发送 FIFO 当前深度 |
| 0x50 | IC_RXFLR | 32 | 接收 FIFO 当前深度 |
| 0x60 | IC_DMA_CR | 32 | DMA 控制寄存器 |
| 0x64 | IC_DMA_RDLR | 32 | DMA 接收数据长度寄存器 |
| 0x68 | IC_DMA_TDLR | 32 | DMA 发送数据长度寄存器 |
4.2 FIFO 机制
RK I2C 控制器内部包含两个独立的 8 字节硬件 FIFO:发送 FIFO(TX FIFO)和接收 FIFO(RX FIFO)。FIFO 机制有效缓解了 CPU 与 I2C 总线之间的速度差异,减少了中断频率。
4.2.1 FIFO 结构与操作
- 发送 FIFO(TX FIFO):深度 8 字节,CPU 通过写 IC_DATA_CMD 寄存器将数据压入。当 FIFO 未满时,硬件自动将数据移出并驱动 SDA 线发送。
- 接收 FIFO(RX FIFO):深度 8 字节,硬件从 SDA 线接收数据后自动存入。CPU 通过读 IC_DATA_CMD 寄存器取出数据。
- 阈值中断:通过 IC_TX_TL 和 IC_RX_TL 设置触发中断的 FIFO 深度。例如 TX_TL=4 表示发送 FIFO 中数据少于 4 字节时触发发送中断。
- 状态查询:IC_TXFLR 和 IC_RXFLR 寄存器实时反映当前 FIFO 中的数据个数,驱动可通过轮询方式使用。
- 写 IC_TX_TL 设置发送阈值(通常设为 FIFO 深度的一半,即 4)。
- 写 IC_RX_TL 设置接收阈值(通常设为 1,收到一个字节即触发)。
- 使能发送/接收中断(IC_INTR_MASK 寄存器)。
- 向 IC_DATA_CMD 写入待发送数据,硬件自动发送。
- 中断触发后,在 ISR 中读取 IC_RXFLR 判断接收数据个数,循环读取 IC_DATA_CMD。
- 传输完成后清除中断状态(写 IC_CLR_INTR)。
4.2.2 FIFO 与中断协同 SVG 流程图
4.3 DMA 支持
当传输数据量较大(通常超过 8 字节)时,PIO(Programmed I/O)模式会频繁触发中断,占用大量 CPU 资源。RK I2C 控制器内置 DMA 接口,支持与系统 DMA 控制器协同工作,实现数据在内存与 I2C FIFO 之间的直接传输,无需 CPU 逐字节干预。
4.3.1 DMA 传输模式
- 发送 DMA:DMA 控制器从内存缓冲区读取数据,写入 I2C 的 TX FIFO。当 TX FIFO 非满时,DMA 自动填充。
- 接收 DMA:DMA 控制器从 I2C 的 RX FIFO 读取数据,写入内存缓冲区。当 RX FIFO 非空时,DMA 自动搬移。
- 突发传输:支持 4 字节或 8 字节突发,提高总线利用率。
4.3.2 DMA 配置步骤
- 在设备树中为 I2C 节点添加 dmas 和 dma-names 属性,指定 DMA 通道。
- 驱动初始化时调用 dma_request_chan() 获取 DMA 通道句柄。
- 配置 IC_DMA_CR 寄存器:bit[0] 使能发送 DMA,bit[1] 使能接收 DMA。
- 设置 IC_DMA_TDLR 和 IC_DMA_RDLR 寄存器,指定 DMA 传输的数据长度。
- 提交 DMA 描述符(dmaengine_prep_slave_single),启动 DMA 传输。
- 传输完成后,DMA 回调函数通知 I2C 驱动,驱动检查状态并结束本次传输。
- DMA 传输要求数据缓冲区物理地址连续,驱动中应使用 dma_alloc_coherent() 或确保 kmalloc 分配的缓冲区已对齐。
- DMA 传输长度必须与 IC_DMA_TDLR/RDLR 寄存器设置一致,否则可能导致数据错位。
- 在 DMA 传输过程中,CPU 不应直接读写 IC_DATA_CMD 寄存器,否则会破坏 FIFO 数据一致性。
- RK 平台 DMA 通道资源有限,多个外设共享 DMA 控制器,驱动需做好通道释放与重试逻辑。
4.3.3 DMA 与 PIO 模式对比
| 对比项 | PIO 模式 | DMA 模式 |
|---|---|---|
| CPU 参与度 | 每字节/每阈值触发中断,CPU 逐字节处理 | 仅启动和完成时 CPU 介入,中间无中断 |
| 传输效率 | 低,大量中断开销 | 高,适合大块数据(>8 字节) |
| 适用场景 | 小数据量(寄存器读写、配置命令) | 大数据量(图像数据、传感器数据流) |
| 驱动复杂度 | 低,仅需 FIFO 和中断管理 | 高,需 DMA 通道申请、描述符管理、回调处理 |
| 内存要求 | 无特殊要求 | 缓冲区需物理连续、对齐 |
4.4 时钟频率配置
RK I2C 控制器的时钟频率由 APB 总线时钟(PCLK)分频得到。核心思想是通过配置 SCL 高电平和低电平的计数寄存器,精确控制 SCL 时钟周期。
4.4.1 频率计算公式
SCL 时钟频率由以下公式决定:
f_SCL = f_PCLK / (SCL_HCNT + SCL_LCNT + 7)
其中:
- f_PCLK:APB 总线时钟频率(通常为 100 MHz 或 200 MHz)
- SCL_HCNT:IC_xx_SCL_HCNT 寄存器值(高电平计数)
- SCL_LCNT:IC_xx_SCL_LCNT 寄存器值(低电平计数)
- 7:硬件固定的额外延迟周期(包括上升/下降时间补偿)
4.4.2 标准模式配置示例
假设 PCLK = 100 MHz,目标频率 100 Kbps(标准模式):
目标周期 T_SCL = 1 / 100000 = 10 µs
PCLK 周期 T_PCLK = 1 / 100000000 = 10 ns
总计数 = T_SCL / T_PCLK - 7 = 10000 / 10 - 7 = 993
通常 SCL_HCNT = SCL_LCNT = 总计数 / 2 = 496(取整)
实际频率 = 100000000 / (496 + 496 + 7) ≈ 100.1 KHz
4.4.3 快速模式配置示例
目标频率 400 Kbps:
目标周期 T_SCL = 1 / 400000 = 2.5 µs = 2500 ns
总计数 = 2500 / 10 - 7 = 243
SCL_HCNT = SCL_LCNT = 121
实际频率 = 100000000 / (121 + 121 + 7) ≈ 401.6 KHz
4.4.4 时钟配置寄存器选择
RK I2C 控制器为三种速度模式分别提供了独立的计数寄存器,驱动根据 IC_CON 中设置的速度模式自动选择对应的寄存器组:
| 速度模式 | IC_CON bit[2:1] | 高电平计数寄存器 | 低电平计数寄存器 |
|---|---|---|---|
| 标准模式(Standard) | 00 | IC_SS_SCL_HCNT (0x14) | IC_SS_SCL_LCNT (0x18) |
| 快速模式(Fast) | 01 | IC_FS_SCL_HCNT (0x1C) | IC_FS_SCL_LCNT (0x20) |
| 高速模式(High Speed) | 10 | IC_HS_SCL_HCNT (0x24) | IC_HS_SCL_LCNT (0x28) |
4.4.5 时钟配置流程 SVG 图
4.5 硬件特性总结
RK I2C 控制器硬件特性可归纳为以下关键点:
- 寄存器模型:基于 Synopsys DesignWare 核,寄存器布局标准,驱动可复用性高。
- FIFO 深度:8 字节 TX/RX FIFO,配合阈值中断实现高效小数据量传输。
- DMA 接口:支持发送和接收 DMA,适合大数据量场景,需注意缓冲区物理连续性和通道管理。
- 时钟配置:通过 HCNT/LCNT 寄存器精确分频,支持标准/快速/高速三种模式,配置前必须关闭控制器。
- 中断管理:提供丰富的中断状态位,包括传输完成、FIFO 阈值、总线错误、仲裁丢失等。
- 确认 SoC 中 I2C 控制器编号及对应的中断号、DMA 通道号。
- 查阅芯片手册获取 PCLK 时钟频率(通常在 100 MHz ~ 200 MHz 之间)。
- 根据目标传感器速率选择合适的速度模式,计算并配置 HCNT/LCNT。
- 根据传输数据量大小选择 PIO 或 DMA 模式:小于 8 字节用 PIO,大于 8 字节用 DMA。
- 验证 FIFO 阈值设置是否合理,避免频繁中断或 FIFO 溢出。