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 发送数据长度寄存器
关键寄存器提示:IC_CON 寄存器的 bit[2:1] 控制速度模式(00=标准,01=快速,10=高速),bit[6] 控制主/从模式。IC_DATA_CMD 寄存器的 bit[8] 控制读写方向(1=读,0=写),bit[0:7] 为数据字节。驱动初始化时必须按顺序配置:IC_ENABLE=0 → 配置时钟计数 → 配置 IC_CON → 配置 IC_TAR → IC_ENABLE=1。

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 中的数据个数,驱动可通过轮询方式使用。
FIFO 操作流程(中断模式):
  1. 写 IC_TX_TL 设置发送阈值(通常设为 FIFO 深度的一半,即 4)。
  2. 写 IC_RX_TL 设置接收阈值(通常设为 1,收到一个字节即触发)。
  3. 使能发送/接收中断(IC_INTR_MASK 寄存器)。
  4. 向 IC_DATA_CMD 写入待发送数据,硬件自动发送。
  5. 中断触发后,在 ISR 中读取 IC_RXFLR 判断接收数据个数,循环读取 IC_DATA_CMD。
  6. 传输完成后清除中断状态(写 IC_CLR_INTR)。

4.2.2 FIFO 与中断协同 SVG 流程图

RK I2C FIFO 与中断协同流程图 CPU 驱动层 TX FIFO 深度 8 字节 RX FIFO 深度 8 字节 I2C 总线 SCL / SDA 中断控制器 TX_TL / RX_TL 写数据 自动发送 自动接收 读数据 触发条件 IRQ 说明: 1. CPU 写 IC_DATA_CMD 将数据送入 TX FIFO,硬件自动移出到 I2C 总线。 2. I2C 总线接收的数据自动存入 RX FIFO,CPU 读 IC_DATA_CMD 取出。 3. 当 FIFO 深度达到阈值(TX_TL/RX_TL)时触发中断,CPU 响应处理。

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 配置步骤

  1. 在设备树中为 I2C 节点添加 dmas 和 dma-names 属性,指定 DMA 通道。
  2. 驱动初始化时调用 dma_request_chan() 获取 DMA 通道句柄。
  3. 配置 IC_DMA_CR 寄存器:bit[0] 使能发送 DMA,bit[1] 使能接收 DMA。
  4. 设置 IC_DMA_TDLR 和 IC_DMA_RDLR 寄存器,指定 DMA 传输的数据长度。
  5. 提交 DMA 描述符(dmaengine_prep_slave_single),启动 DMA 传输。
  6. 传输完成后,DMA 回调函数通知 I2C 驱动,驱动检查状态并结束本次传输。
DMA 使用注意事项:
  • 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 图

RK I2C 时钟频率配置流程图 获取 PCLK 频率 选择速度模式 计算 HCNT / LCNT 写入对应寄存器 使能控制器 寄存器选择规则: 标准模式 → IC_SS_SCL_HCNT/LCNT 快速模式 → IC_FS_SCL_HCNT/LCNT 高速模式 → IC_HS_SCL_HCNT/LCNT 公式: f_SCL = f_PCLK / (HCNT+LCNT+7) HCNT ≈ LCNT ≈ 总计数/2 配置前提: 1. IC_ENABLE = 0 2. 确认 PCLK 时钟已使能 3. 配置完成后才使能

4.5 硬件特性总结

RK I2C 控制器硬件特性可归纳为以下关键点:

  • 寄存器模型:基于 Synopsys DesignWare 核,寄存器布局标准,驱动可复用性高。
  • FIFO 深度:8 字节 TX/RX FIFO,配合阈值中断实现高效小数据量传输。
  • DMA 接口:支持发送和接收 DMA,适合大数据量场景,需注意缓冲区物理连续性和通道管理。
  • 时钟配置:通过 HCNT/LCNT 寄存器精确分频,支持标准/快速/高速三种模式,配置前必须关闭控制器。
  • 中断管理:提供丰富的中断状态位,包括传输完成、FIFO 阈值、总线错误、仲裁丢失等。
驱动开发硬件检查清单:
  1. 确认 SoC 中 I2C 控制器编号及对应的中断号、DMA 通道号。
  2. 查阅芯片手册获取 PCLK 时钟频率(通常在 100 MHz ~ 200 MHz 之间)。
  3. 根据目标传感器速率选择合适的速度模式,计算并配置 HCNT/LCNT。
  4. 根据传输数据量大小选择 PIO 或 DMA 模式:小于 8 字节用 PIO,大于 8 字节用 DMA。
  5. 验证 FIFO 阈值设置是否合理,避免频繁中断或 FIFO 溢出。