RK3576 android14 I2C总线,硬件I2C 与 GPIO模拟I2C 比对

在嵌入式 Linux 板级开发里,接一颗带 I2C 接口的外设时,常常会遇到两种做法:一是走 SoC 自带的 硬件 I2C 控制器,二是用两个 GPIO 软件模拟 成一条 I2C 总线。表面上看,二者在设备树里都能挂出同样的 i2c_client,驱动层也往往无感;但在 速率、波形质量、EMI、休眠与 IO 供电域、以及量产后的稳定性上有所差别。

一,两种方案参数对比

硬件i2c(soc外设控制器) gpio模拟i2c(i2c-gpio)
CRU 提供时钟,内核 i2c-designware 等驱动控制 SCL/SDA 时序 用两个 GPIO 在软件里 bit-bang,每比特多次 GPIO 翻转
易做 100k / 400k / 1M(受 clock-frequency 与从设备能力限制) 实际有效速率明显低于硬件 I2C,且与 delay-us、CPU 负载强相关
需占用 一组复用为 I2C 功能 的管脚(pinctrl 切到 i2cX xfer) 占用 任意 GPIO,功能保持为 GPIO 模式即可
硬件时序规整,上升沿/占空比由控制器与 IO 驱动能力保证 依赖 GPIO 驱动强度、走线、外部上拉;delay-us 过小易误码
控制器可随时钟门控;管脚电平与 IO 电压域(VCCIO)、休眠策略相关 同样受 VCCIO 保持 / 掉电 影响;无独立控制器时钟,但 GPIO 域掉电会直接"哑火"
标准 &i2cN { ... };,子节点 reg 为从机地址 compatible = "i2c-gpio",子设备写法与硬件 I2C 相同(对上层驱动透明)

总结:能走硬件 I2C、且管脚和复用都允许时,优先硬件 I2C;只有布线/复用冲突、或必须"任意脚"接从设备时,再用 GPIO 模拟,并接受速率、可靠性与休眠场景上的额外工程成本。


二,硬件 I2C

典型硬件 I2C:使能控制器、pinctrl 切到 I2C 复用、下面挂 reg = <0x**> 等子设备。

举个例子:

bash 复制代码
&i2c6 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&i2c6m3_xfer>;

	sgm41542: sgm41542@3b {
		compatible = "sgm,sgm41542";
		status = "okay";
		reg = <0x3b>;
		extcon = <&u2phy0>, <&usbc0>;
		pinctrl-names = "default";
		pinctrl-0 = <&charger_ok>;
		interrupt-parent = <&gpio0>;
		interrupts = <RK_PD2 IRQ_TYPE_EDGE_FALLING>;
		otg-mode-en-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_HIGH>;
		input-voltage-limit-microvolt = <4500000>;
		input-current-limit-microamp = <3000000>;
		monitored-battery = <&bat>;
		regulators {
			vbus5v0_typec: vbus5v0-typec {
				regulator-compatible = "otg-vbus";
				regulator-name = "vbus5v0_typec";
			};
		};
	};

pinctrl-0 = <&i2c6m3_xfer> ; 表示 SCL/SDA 在 芯片复用功能 上,由 I2C 控制器驱动,而不是软件 toggling。
clock-frequency; 直接约束总线速率;与 i2c-gpio,delay-us 的调参逻辑完全不同。


三、GPIO 模拟 I2C

当硬件I2C控制器资源不足或需要特殊引脚配置时,GPIO模拟方案提供了灵活的替代选择。GPIO子系统支持开漏(OD)模式,可直接模拟I2C总线所需的线"与"特性。

举个例子:

bash 复制代码
/* GPIO 模拟 I2C 控制器节点:对内核表现为一个 i2c_adapter */
i2c_nfc: i2c-nfc {
	compatible = "i2c-gpio";

	/* SDA/SCL 必须为开漏语义:ACTIVE_HIGH | OPEN_DRAIN */
	sda-gpios = <&gpio2 RK_PD1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
	scl-gpios = <&gpio2 RK_PD0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;

	/*
	 * 每步 GPIO 操作之间的延时;过小易在长线/大电容总线上 NACK/丢包,
	 * 过大则降低有效速率。需结合示波器与 NFC 芯片手册在板级微调。
	 */
	i2c-gpio,delay-us = <20>;

	#address-cells = <1>;
	#size-cells = <0>;

	pinctrl-names = "default";
	/* 将相关脚固定为 GPIO 功能及 IRQ 脚上下拉 */
	pinctrl-0 = <&i2c_nfc_gpio &nfc_int_gpio>;
	status = "okay";

	/* 下游子设备写法与硬件 I2C 总线上一致 */
	nfc@38 {
		compatible = "nxp,nxpnfc";
		reg = <0x38>;
		interrupt-parent = <&gpio2>;
		interrupts = <RK_PC6 IRQ_TYPE_LEVEL_HIGH>;
		nxp,nxpnfc-irq = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
	};
};

aliases 里把 i2c10 指到 i2c_nfc,方便用户空间或文档用「逻辑编号」指代这条模拟总线:

bash 复制代码
		i2c8 = &i2c8;
		i2c9 = &i2c9;
		i2c10 = &i2c_nfc;
		i3c0 = &i3c0;

硬件 I2C 与 GPIO 模拟 I2C 都可能受 IO 电压域、休眠漏电策略影响;但 GPIO 模拟完全依赖 两根数据线处于合法空闲态(通常靠外部上拉 + 软件释放总线),一旦休眠路径上 IO 断电或态丢失,从设备可能锁死、需要掉电复位。


四,如何「抉择」?

  1. 优先选择硬件I2C控制器的场景:

高速数据传输(>100kHz)

多设备总线拓扑

实时性要求高的系统

需要DMA支持的批量传输

产品量产方案

  1. GPIO模拟I2C更合适的场景:

引脚资源紧张时的临时方案

特殊时序要求的设备

原型开发阶段的快速验证

低频(<10kHz)单设备通信

需要动态切换引脚的功能

实际项目里:只要原理图能把从设备的 SCL/SDA 接到 SoC 上可用的硬件 I2C 复用脚、且速率与可靠性有要求,就优先用硬件 I2C;只有在管脚/复用/布线已定型无法改线、或必须用普通 GPIO 才能接到从设备时,再接受 GPIO 模拟 I2C,并预留好上拉、位时序(如 delay-us)和休眠/供电域相关的联调成本。

相关推荐
SM177152118386 天前
NSK紧凑型FA系列丝杠技术详解
经验分享·规格说明书
u152109648496 天前
S.S.Audio PRO A2音频隔离器
嵌入式硬件·音视频·实时音视频·视频编解码·视频
zd8451015006 天前
RS485 总线详解
单片机·嵌入式硬件
半条-咸鱼6 天前
【STM32】I2C协议原理、HAL读写与OLED显示操作
嵌入式硬件·c·信息与通信
fofantasy6 天前
NSK SFT3210-2.5 滚珠丝杠技术详解
经验分享·规格说明书
wohoo_wangzi6 天前
苏州晟雅泰电子:关于W25Q128JVSIQ这个芯片物料的参数,规格及应用领域
嵌入式硬件
BomanGe106 天前
NSK USS1205N1D0321 紧凑型精密滚珠丝杠技术详解
经验分享·规格说明书
阿米亚波6 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
AIHR数智引擎6 天前
KPI物理失效:AI原生组织的效能重构与技能度量
人工智能·经验分享·职场和发展·重构·ai-native·aihr
科芯创展7 天前
1A,1MHz,30VIN,XZ4115,降压恒流LED驱动芯片
单片机·嵌入式硬件