3. Sensor 初始化序列
Sensor 的初始化是 MIPI 链路正常工作的前提。一个完整的初始化序列必须严格遵循硬件时序要求,并通过 I²C 或 SPI 总线完成寄存器配置,最终锁定 PLL 并确定输出数据格式。任何一步的时序或参数错误,都会导致链路无法建立或图像异常。
3.1 上电时序(Power-Up Sequence)
Sensor 对上电顺序有严格要求,通常遵循:模拟电源(AVDD)→ 数字电源(DVDD)→ I/O 电源(IOVDD)→ 主时钟(MCLK)→ 复位释放(XSHUTDOWN)。违反时序可能导致 sensor 内部逻辑混乱、寄存器无法写入,甚至物理损坏。
关键指标: 各电源之间的延迟时间(T1、T2、T3)通常在 datasheet 中以微秒(μs)或毫秒(ms)为单位给出。驱动代码中必须通过
mdelay() 或 usleep_range() 精确实现。
典型上电时序参数表(以 OV5640 为例):
| 步骤 | 动作 | 最小延迟 | 说明 |
|---|---|---|---|
| 1 | AVDD 上电(2.8V) | 0 μs | 模拟电源先稳定 |
| 2 | DVDD 上电(1.5V) | ≥ 100 μs | 相对 AVDD 延迟 |
| 3 | IOVDD 上电(1.8V) | ≥ 100 μs | 相对 DVDD 延迟 |
| 4 | MCLK 提供时钟 | ≥ 1 ms | 所有电源稳定后 |
| 5 | XSHUTDOWN 拉高 | ≥ 1 ms | 时钟稳定后释放复位 |
| 6 | I²C 初始化 | ≥ 5 ms | 等待内部 PLL 稳定 |
3.2 寄存器配置(Register Configuration)
上电完成后,驱动通过 I²C 总线向 sensor 写入初始化寄存器序列。这些寄存器控制 sensor 的工作模式、曝光、增益、帧率、输出尺寸等。常见的配置方式有两种:
- 直接写入: 逐个写入寄存器地址和值,适用于少量配置。
- 表格驱动: 使用预定义的寄存器数组(
struct regval_list),批量写入,适用于复杂初始化。
寄存器配置示例(C 语言驱动片段):
/* 寄存器-值对结构体 */
struct regval_list {
uint16_t addr;
uint8_t val;
};
/* 初始化序列表格 */
static const struct regval_list sensor_init_regs[] = {
{0x0103, 0x01}, /* 软件复位 */
{0x3035, 0x11}, /* PLL 分频配置 */
{0x3036, 0x46}, /* PLL 倍频配置 */
{0x3820, 0x41}, /* 镜像/翻转设置 */
{0x3821, 0x01}, /* 输出顺序 */
{0x3714, 0x28}, /* 模拟电路配置 */
{0x3715, 0x12}, /* 模拟电路配置 */
{0x3808, 0x05}, /* 输出宽度高字节 */
{0x3809, 0x10}, /* 输出宽度低字节 (1296) */
{0x380A, 0x04}, /* 输出高度高字节 */
{0x380B, 0x38}, /* 输出高度低字节 (972) */
{0x380C, 0x07}, /* 总宽度高字节 */
{0x380D, 0x68}, /* 总宽度低字节 */
{0x380E, 0x04}, /* 总高度高字节 */
{0x380F, 0x98}, /* 总高度低字节 */
{0x501F, 0x01}, /* ISP 使能 */
{0x5000, 0x06}, /* 色彩处理使能 */
{0x5180, 0x00}, /* 自动白平衡配置 */
{0x5181, 0x00},
{0x5182, 0x00},
{0x5183, 0x00},
{0x0100, 0x01}, /* 启动流控 */
};
/* 批量写入函数 */
static int sensor_write_regs(struct i2c_client *client,
const struct regval_list *regs, int len)
{
int i, ret;
for (i = 0; i < len; i++) {
ret = sensor_write_reg(client, regs[i].addr, regs[i].val);
if (ret < 0)
return ret;
usleep_range(100, 200); /* 寄存器间延迟 */
}
return 0;
}
3.3 PLL 锁相环设置(PLL Configuration)
PLL 用于将外部输入的主时钟(MCLK)倍频到 sensor 内部所需的工作时钟。输出像素时钟(PCLK)和 MIPI 数据速率直接由 PLL 配置决定。典型的 PLL 计算公式如下:
VCO = MCLK × PLL_MULT / PLL_DIV
PCLK = VCO / PLL_POST_DIV
MIPI_BIT_CLK = PCLK × 每个时钟周期的比特数
常见问题: PLL 配置不当会导致输出帧率不准、MIPI 数据速率超出 PHY 支持范围、图像闪烁或花屏。务必使用 datasheet 提供的参考值作为起点。
| 参数 | 符号 | 示例值(24MHz MCLK) | 说明 |
|---|---|---|---|
| 输入时钟 | MCLK | 24 MHz | 外部晶振或 SoC 提供 |
| 倍频系数 | PLL_MULT | 46 | 寄存器 0x3036 设置 |
| 分频系数 | PLL_DIV | 2 | 寄存器 0x3035 设置 |
| VCO 频率 | VCO | 552 MHz | 24 × 46 / 2 |
| 后分频 | PLL_POST_DIV | 4 | 内部固定或可配 |
| 像素时钟 | PCLK | 138 MHz | 552 / 4 |
| MIPI 数据速率 | MIPI_CLK | 552 Mbps/lane | 138 × 4(DDR) |
3.4 输出格式选择(RAW10 / RAW12 / YUV)
Sensor 的输出格式决定了图像数据的位深和色彩空间。不同格式对 MIPI 链路的带宽需求差异显著,驱动中需通过寄存器选择对应的输出模式。
| 格式 | 位深 | 每像素比特 | 典型应用 | 带宽需求(相对) |
|---|---|---|---|---|
| RAW8 | 8-bit | 8 | 低端摄像头、快速预览 | 低 |
| RAW10 | 10-bit | 10 | 主流手机、安防、工业 | 中 |
| RAW12 | 12-bit | 12 | 高动态范围、医疗、科研 | 高 |
| YUV422 | 8-bit | 16 | 视频通话、编码输入 | 中高 |
| JPEG | 压缩 | 可变 | 拍照、存储 | 低(压缩后) |
格式选择寄存器示例:
/* 设置输出格式为 RAW10 */
sensor_write_reg(client, 0x4300, 0x30); /* 格式控制寄存器 */
/* 0x30: RAW10, 0x00: RAW8, 0x32: RAW12, 0x40: YUV422 */
/* 设置 MIPI 数据包格式 */
sensor_write_reg(client, 0x4601, 0x00); /* 0x00: RAW10 打包模式 */
避坑指南: 切换输出格式后,必须同步更新 MIPI 的
mipi_fmt 配置,否则接收端(CSI 控制器)会解析错误。例如 RAW10 使用 4 个字节存储 4 个像素(打包模式),而 RAW12 使用 3 个字节存储 2 个像素。
3.5 初始化序列完整流程
将上述步骤整合,一个完整的 sensor 初始化序列如下:
- 硬件上电: 按 AVDD → DVDD → IOVDD 顺序供电,每步间隔 ≥ 100 μs。
- 时钟提供: 使能 MCLK,等待 ≥ 1 ms。
- 复位释放: 拉高 XSHUTDOWN 引脚,等待 ≥ 1 ms。
- I²C 通信检测: 读取 sensor ID 寄存器,确认通信正常。
- 写入初始化寄存器: 批量写入 PLL、输出尺寸、格式、模拟电路等配置。
- PLL 锁定等待: 轮询 PLL 锁定状态寄存器,或固定延迟 ≥ 5 ms。
- 启动流控: 写入 0x0100 = 0x01,使能 sensor 输出。
- MIPI 链路检测: 检查 CSI 接收端是否收到有效的同步码(SoT/EoT)。
调试建议: 在驱动中增加
dev_dbg() 打印每个步骤的执行状态,配合逻辑分析仪抓取 I²C 波形和 MIPI 数据 lane 信号,可以快速定位初始化失败的具体环节。