1. Sensor驱动基础:MIPI CSI-2协议概述、Sensor硬件接口与上电时序

各位同学,咱们今天正式开始Sensor驱动移植调试的第一课。说实话,做嵌入式驱动这么多年,我见过太多工程师一上来就对着datasheet猛写代码,结果Sensor死活不出图。问题出在哪儿?往往是基础没打牢。

这一章,咱们就把Sensor驱动的地基夯实。我会从MIPI CSI-2协议讲起,然后聊硬件接口,最后重点说上电时序——这块儿坑最多,我当年可没少在这上面栽跟头。

1.1 MIPI CSI-2协议概述

MIPI CSI-2,全称是Camera Serial Interface 2。说白了,就是摄像头和处理器之间传图像数据的标准协议。你想想看,Sensor采集到的原始图像数据量有多大?1080p@30fps的RAW10数据,带宽就要将近500Mbps。要是用并口传,PCB走线能把你逼疯。

CSI-2用差分信号传输,一对差分线就能跑几百Mbps到几Gbps。它定义了物理层、协议层和应用层三层架构。我习惯把这三层理解成:

  • 物理层(D-PHY):负责信号的电气特性,比如电压摆幅、时钟频率、差分阻抗。说白了就是“怎么把0和1发出去”。
  • 协议层:负责数据打包、解包、错误检测。定义了长包、短包、ECC校验等。相当于“数据怎么组织”。
  • 应用层:定义图像格式、帧结构、元数据。比如RAW10、YUV422这些格式怎么排列。这就是“数据长什么样”。

核心概念:CSI-2的传输基本单位是包(Packet)。分为短包(Short Packet,8字节)和长包(Long Packet,可变长度)。短包通常用来传帧开始、帧结束、行开始等同步信号;长包用来传实际的图像数据。

下面这张图,是我自己总结的CSI-2协议栈结构,你一看就明白:

MIPI CSI-2 协议栈结构 应用层(Application Layer) 图像格式:RAW8/10/12、YUV422、JPEG | 帧结构:FS/FE/LS/LE 协议层(Protocol Layer) 长包/短包 | ECC校验 | CRC校验 | 虚拟通道(VC) 物理层(D-PHY) 差分信号 | 时钟通道+数据通道 | HS/LP模式 | 1.2V/1.8V电平 💡 说明: CSI-2最多支持4条数据通道(Lane),每条Lane独立传输数据。 时钟通道和数据通道之间必须满足skew要求,否则数据会错位。

我的经验:调试CSI-2时,我习惯先看物理层能不能锁定。用示波器量时钟通道的差分信号,看摆幅是否在200mV以上。如果时钟都锁不住,协议层和应用层根本不用看。我曾经花了两天查一个图像花屏的问题,最后发现是PCB上CSI-2差分对的等长没做好,差了3mm——嗯,从那以后我画板子都要求等长控制在1mm以内。

1.2 Sensor硬件接口:I2C/SPI/GPIO

Sensor和主控之间,除了MIPI传图像数据,还需要控制接口。说白了,主控要通过控制接口来配置Sensor的寄存器,比如设置曝光时间、增益、输出分辨率等。

常用的控制接口有三种:I2C、SPI和GPIO。我一个个说。

1.2.1 I2C接口

I2C是Sensor最常用的控制接口。两根线:SCL(时钟)和SDA(数据)。速度一般跑100kHz或400kHz,有些Sensor支持1MHz。OV5640和IMX系列基本都是I2C接口。

I2C的时序其实不复杂,但有几个细节容易翻车:

  • 地址问题:Sensor的I2C地址通常是7位或10位。OV5640的7位地址是0x3C,写操作是0x78,读操作是0x79。IMX系列有些是0x1A或0x20。一定要看datasheet确认。
  • 寄存器地址宽度:OV5640的寄存器地址是16位,所以I2C写操作要先发高8位地址,再发低8位地址。IMX系列有些是8位地址。这个搞错了,写寄存器全白写。
  • ACK/NACK:每次发送完一个字节,都要等从设备的ACK。如果没等到,说明设备没响应。我调试时经常用逻辑分析仪抓I2C波形,看ACK位有没有拉低。

⚠️ 常见坑:有些Sensor的I2C地址可以通过引脚电平配置。比如OV5640的I2C地址由SIO_1V8和SIO_2V8引脚决定。如果你板子上这两个引脚电平不对,I2C地址就变了,主控怎么都扫不到设备。我遇到过一回,查了三天才发现是原理图上地址配置引脚悬空了。

1.2.2 SPI接口

SPI用得少一些,但有些Sensor(比如部分工业相机Sensor)用SPI做控制接口。SPI有四根线:SCLK、MOSI、MISO、CS。速度可以跑到几十MHz,比I2C快得多。

SPI的配置参数:

参数 常见值 说明
时钟极性(CPOL) 0 或 1 空闲时时钟电平,0为低,1为高
时钟相位(CPHA) 0 或 1 数据采样沿,0为第一个边沿,1为第二个边沿
数据位宽 8位 大部分Sensor是8位,少数支持16位
MSB/LSB MSB First 大部分Sensor是高位在前

我个人建议,用SPI时先看Sensor的datasheet里有没有时序图。照着时序图配CPOL和CPHA,一般不会错。如果配反了,读回来的数据全是乱的。

1.2.3 GPIO接口

GPIO在Sensor驱动里主要用来做控制信号,比如:

  • 复位(RESET):拉低复位Sensor,拉高释放复位。
  • 电源使能(PWDN/STANDBY):控制Sensor进入低功耗模式或唤醒。
  • 帧同步(VSYNC/FSYNC):有些Sensor支持外部帧同步,用GPIO触发。
  • 中断输出(INT):Sensor检测到事件(比如曝光完成)时拉高/拉低。

我的习惯:GPIO的驱动能力要留意。有些Sensor的复位引脚需要较大的灌电流,如果主控GPIO驱动能力不够,复位电平可能拉不到底。我一般会在GPIO和Sensor之间加一个三极管或电平转换芯片,确保信号质量。

1.3 Sensor上电时序与复位逻辑

这块儿是Sensor驱动里最容易出问题的地方。说句实话,我见过的Sensor不出图案例里,有一半以上是上电时序不对。

Sensor内部有多个电源域:模拟电源(AVDD)、数字电源(DVDD)、IO电源(IOVDD)。这些电源的上电顺序有严格要求。为什么?因为如果先给IO供电,再给核心供电,IO引脚的ESD保护电路可能处于不确定状态,导致漏电甚至损坏。

以OV5640为例,典型的上电时序要求:

  1. 先上DVDD(1.5V),等待至少1ms
  2. 再上AVDD(2.8V),等待至少1ms
  3. 最后上IOVDD(1.8V或2.8V),等待至少1ms
  4. 拉高RESET引脚,释放复位
  5. 等待至少20ms,让Sensor内部PLL稳定
  6. 通过I2C配置寄存器

IMX系列的要求类似,但具体时序参数不同。比如IMX219要求:

步骤 动作 最小延时 说明
1 拉低RESET和PWDN 0ms 确保Sensor处于复位状态
2 上DVDD(1.2V) 0ms 数字核心供电
3 上IOVDD(1.8V) ≥1ms IO接口供电
4 上AVDD(2.8V) ≥1ms 模拟供电
5 拉高RESET ≥5ms 释放复位
6 拉高PWDN ≥1ms 退出待机模式
7 等待PLL稳定 ≥20ms 开始I2C配置

关键点:上电时序的延时不是越长越好。延时太长,系统启动会变慢;延时太短,Sensor内部状态机可能还没准备好。我建议严格按照datasheet的典型值来,不要自己拍脑袋改。如果datasheet没给具体值,保守起见用10ms作为最小间隔。

下面这张时序图,是我用SVG画的OV5640上电流程,你对照着看:

OV5640 上电时序流程图 1. 上DVDD (1.5V) 2. 上AVDD (2.8V) 3. 上IOVDD (1.8V) 4. 拉高RESET 5. I2C配置寄存器 ≥1ms ≥1ms ≥1ms ≥20ms ⚠️ 注意:RESET拉高后必须等待至少20ms,让Sensor内部PLL和MIPI PHY稳定,才能开始I2C配置。 如果上电顺序反了,Sensor可能无法正常初始化,甚至损坏。

⚠️ 我曾经踩过的坑:有一次调试IMX258,上电时序完全按照datasheet来的,但Sensor就是不出图。用示波器量RESET引脚,发现拉高后有个200ms的毛刺——原来是主控GPIO默认输出低电平,初始化过程中先拉高再拉低再拉高。这个毛刺导致Sensor复位了两次,内部状态机乱了。从那以后,我都在上电前先把GPIO拉到确定状态,再按顺序操作。

复位逻辑也要注意。大部分Sensor支持硬件复位(RESET引脚)和软件复位(写寄存器)。硬件复位更彻底,会把所有寄存器恢复到默认值。软件复位只复位部分逻辑,有些配置会保留。

我个人的建议是:

  • 首次上电时,用硬件复位,确保Sensor处于已知状态。
  • 运行过程中需要复位时,优先用软件复位,避免重新走一遍上电时序。
  • 如果软件复位后Sensor行为异常,再考虑硬件复位。

好了,这一章的内容就这些。MIPI CSI-2协议、硬件接口、上电时序,这三块是Sensor驱动的基础。你把这些搞清楚了,后面写驱动代码的时候就会顺手很多。