3、硬件接口解析:MIPI CSI-2协议、I2C控制接口、GPIO与复位时序
好,咱们进入第三讲。这一讲我打算把Camera驱动里最绕不开的三个硬件接口掰开揉碎了讲清楚。MIPI CSI-2、I2C、GPIO和复位时序,这三样东西你搞不明白,后面移植代码就是瞎蒙。
我个人习惯,拿到一块新的Sensor模组,第一件事不是看驱动代码,而是先翻Datasheet里的这三部分。为什么?因为硬件接口决定了你的软件怎么跟Sensor“对话”。
3.1 MIPI CSI-2协议:图像数据的“高速公路”
MIPI CSI-2,说白了就是摄像头和SoC之间传图像数据的协议。它用的是差分信号,抗干扰能力强,速度也快。
你想想看,一个1080P@30fps的摄像头,一秒钟要传多少数据?大概3Gbps左右。普通的并行接口根本扛不住,所以MIPI CSI-2就成了主流。
3.1.1 物理层:D-PHY
CSI-2的物理层通常是D-PHY。它由时钟通道(Clock Lane)和数据通道(Data Lane)组成。数据通道可以配成1、2、4条,甚至更多。
我记得在瑞萨R-Car平台上,最常见的是4条数据通道加1条时钟通道。每条数据通道的速率可以跑到1Gbps以上。
| 参数 | 典型值 | 说明 |
|---|---|---|
| 数据通道数 | 1/2/4 Lane | 根据分辨率选,4K建议4 Lane |
| 每通道速率 | 400Mbps - 2.5Gbps | 取决于Sensor和SoC能力 |
| 时钟频率 | 200MHz - 1.25GHz | 一般是数据速率的一半 |
3.1.2 协议层:数据包格式
CSI-2的数据是以包(Packet)为单位传输的。每个包有包头(Header)和包尾(Footer)。包头里包含了数据类型、虚拟通道号等信息。
这里有个关键点:数据类型(Data Type, DT)。它告诉接收端这一包数据是什么。比如:
- 0x2B:RAW10格式的图像数据
- 0x2C:RAW12格式的图像数据
- 0x1E:YUV422 8bit格式
我在项目中遇到过一个问题:Sensor输出的明明是RAW10,但驱动里配成了RAW12。结果图像全是花屏,查了两天才发现是数据类型配错了。嗯,这种低级错误最容易犯。
重要提醒:MIPI CSI-2的时钟通道必须稳定。如果时钟抖动太大,图像会出现条纹或者丢帧。建议在PCB布局时,时钟线要包地处理。
3.2 I2C控制接口:Sensor的“遥控器”
MIPI传的是图像数据,那Sensor的寄存器怎么配置?曝光时间、增益、帧率这些参数怎么调?靠的就是I2C。
I2C只有两根线:SCL(时钟)和SDA(数据)。Sensor作为从设备,SoC作为主设备。SoC通过I2C往Sensor的寄存器里写值,Sensor就按你的要求工作了。
3.2.1 I2C地址与寄存器访问
每个Sensor都有一个I2C设备地址,通常是7位或10位。比如OV5640的地址是0x3C(写)和0x3D(读)。
访问寄存器时,一般是先发设备地址,再发寄存器地址,最后发数据。举个例子:
// 往Sensor的0x3008寄存器写0x80
// 伪代码示意
i2c_write(dev_addr=0x3C, reg_addr=0x3008, data=0x80);
这里要注意寄存器地址的宽度。有些Sensor是8位寄存器地址,有些是16位。瑞萨的R-Car平台I2C控制器支持自动地址宽度检测,但最好在驱动里明确指定。
我的习惯:写I2C驱动时,先读一下Sensor的ID寄存器。如果读回来的值跟Datasheet对不上,说明I2C通信有问题。这是最快速的硬件调试方法。
3.2.2 I2C速率与上拉电阻
I2C的标准速率是100kHz,快速模式是400kHz。但很多Sensor支持1MHz甚至更高。
不过速率不是越高越好。我曾经在一个项目里把I2C速率设成了1MHz,结果Sensor偶尔会应答失败。后来发现是PCB走线太长,信号反射导致的。降到400kHz就稳定了。
上拉电阻也很关键。一般I2C总线上拉电阻选4.7kΩ。如果总线电容大,可以换成2.2kΩ。但别太小,否则功耗会上去。
3.3 GPIO与复位时序:Sensor的“生命线”
GPIO在Camera驱动里主要干两件事:复位(Reset)和电源使能(Power Enable)。
复位时序,说白了就是Sensor上电后,怎么让它进入正常工作状态。这个时序如果搞错了,Sensor可能根本不会输出图像。
3.3.1 标准复位时序
大部分Sensor的复位时序是这样的:
- 拉低复位引脚(RST),保持至少1ms
- 拉高复位引脚,释放复位
- 等待至少10ms,让Sensor内部初始化完成
- 开始通过I2C配置寄存器
但不同Sensor的时序要求不一样。有的要求复位低电平保持5ms,有的要求10ms。一定要看Datasheet里的时序图。
注意:有些Sensor的复位引脚是低电平有效,有些是高电平有效。接反了Sensor就永远处于复位状态。我见过有人把复位引脚直接接VCC,结果Sensor死活不工作。
3.3.2 电源上电顺序
比复位时序更麻烦的是电源上电顺序。Sensor通常需要多路电源:
- AVDD:模拟电源,一般是2.8V或3.3V
- DVDD:数字核心电源,一般是1.2V或1.8V
- IOVDD:I/O电源,一般是1.8V或2.8V
上电顺序通常是:先IOVDD,再AVDD,最后DVDD。或者先AVDD,再DVDD。具体看Datasheet。
我曾经在一个项目里,因为电源上电顺序反了,Sensor的模拟部分和数字部分出现了latch-up(闩锁效应),直接把Sensor烧了。从那以后,我每次画原理图都会再三确认电源时序。
3.3.3 GPIO在驱动中的实现
在瑞萨平台上,GPIO控制通常通过设备树(Device Tree)来配置。比如:
// 设备树中定义复位GPIO
sensor: camera@3c {
compatible = "ovti,ov5640";
reg = <0x3c>;
reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
power-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
};
驱动里通过gpiod_get()获取GPIO句柄,然后用gpiod_set_value()控制电平。注意,GPIO_ACTIVE_LOW表示低电平有效,驱动框架会自动帮你做电平反转。
避坑指南:我曾经在驱动里直接用gpio_set_value()控制复位引脚,结果发现设备树里配的是GPIO_ACTIVE_LOW,但驱动里没做反转。后来改用gpiod_set_value()就对了。记住,用gpiod系列函数,别用老的gpio系列。
3.4 三者之间的关系
MIPI CSI-2、I2C、GPIO这三者是怎么配合的?我画个简单的流程:
- 上电,GPIO控制电源使能
- GPIO控制复位引脚,释放复位
- 等待Sensor初始化完成
- 通过I2C配置Sensor寄存器(分辨率、帧率、增益等)
- Sensor开始通过MIPI CSI-2输出图像数据
- SoC接收数据,进行后续处理
你看,每一步都离不开硬件接口的正确配置。任何一个环节出问题,图像都出不来。
嗯,这一讲的内容就到这里。下一讲我们会深入瑞萨R-Car的MIPI CSI-2控制器驱动,看看怎么在软件层面配置这些接口。到时候我会拿实际代码来演示,你准备好了吗?