# Camera 调试指南

## 范围

- 本章节概述 X5 Camera Bring-Up 的流程，帮助读者快速掌握 X5 Camera 框架。
- 说明如何新增 Camera 配置并成功点亮 Camera。
- 各 Sensor 厂家具体实现（驱动、App、sample程序验证）与常见问题请参见下方「文档组成」中的对应章节。

## 文档组成

| 章节 | 说明 |
|------|------|
| [Camera 调试指南](../../multimedia_development/isp_tuning_guide/Camera_sensor_bringup.html#) | 流程概览、准备工作、设备树与驱动/App 通用说明、验证概要 |
| [OmniVision Sensor Bring-Up](../../multimedia_development/isp_tuning_guide/OmniVision_sensor_bringup.html) | OmniVision 系列 sensor os08c10 驱动、App 配置与程序验证 |
| [SmartSens Sensor Bring-Up](../../multimedia_development/isp_tuning_guide/SmartSens_sensor_bringup.html) | SmartSens 系列 sensor sc132gs 驱动、App 配置与程序验证 |
| [Sony Sensor Bring-Up](../../multimedia_development/isp_tuning_guide/Sony_sensor_bringup.html) | Sony 系列 sensor imx586驱动、App 配置与程序验证 |
| [Camera Sensor FAQ](../../multimedia_development/isp_tuning_guide/Camera_sensor_FAQ.html) | I2C/MCLK/MIPI/Sensor 等常见问题与排查方法 |


建议先通读本文掌握整体步骤与通用配置，再按所选用 sensor 厂家阅读对应分章节。

---

## 准备工作

- **软件资源**：系统 BSP、sensor datasheet、sensor 的初始化序列。
- **硬件资源**：以 EVB 开发板为例及待适配的 Camera 模组、原理图 和pcb。

![image-20240425003534337](./media/Camera_sensor_bringup/image-20240425003534337.png)

上图是 X5 EVB 开发板对应的接口，每个接口对应的相关硬件 IO 资源如下：

| 接口 | MIPI CSI Host | 最大支持 lane 数  | I2C Bus  | Reset GPIO           | LPWM/PWD          |MCLK                 |
| ---- | ------------- | ---------------- | ------- | ------------------- |-------------------|-------------------|
| 20   | MIPI_CSI0&1   | 4 lane           | I2C4    | AON_GPIO_PIN0 - 498 |  LSIO_SPI5_SCLK - lpwm0 | LSIO_SPI3_SCLK - mclk0 |
| 21   | MIPI_CSI2     | 2 lane           | I2C2    | AON_GPIO_PIN4 - 502 |  LSIO_SPI5_SSN - lpwm1 | LSIO_SPI3_MISO - mclk2 |
| 22   | MIPI_CSI3     | 2 lane           | I2C7    | LSIO_GPIO1_06 - 353 |  LSIO_SPI5_MISO - lpwm2 | LSIO_SPI3_MOSI - mclk3 |

X5 MIPI HOST (RX) 系统支持以下配置：

- **单 Host 模式**：每个 Host (0-3) 独立支持 **2 lane**
- **Lane 拼接模式**：Host0+Host1、Host2+Host3 可分别拼接为 **4 lane**；EVB 默认 Host0+Host1 拼接，Host2/Host3 为单 Host。

---

## 新 sensor 点亮步骤

在 X5 平台上适配新 Camera 时，需完成以下步骤（具体操作与示例见各厂家 bringup 文档）：

1. **修改平台设备树 (dts)**：按硬件设计配置 sensor 上电 GPIO、I2C、MCLK、LPWM。
2. **添加 sensor 驱动代码**：实现 `sensor_module_t` 的初始化/反初始化、开流/关流、上下电、增益/曝光控制等接口。
3. **添加 camera App 代码**：配置 MIPI、SIF、camera sensor、LPWM、ISP 等参数。
4. **添加默认 camera ISP 效果库**：准备 `sensor_name_tuning.json`，供 ISP 用例使用。
5. **示例程序运行**：用 get_vin_data / get_isp_data 查看 raw 图、帧率与 ISP 图像是否符合预期。
6. **ISP 图像调试预览**：连接 hbplayer，验证驱动增益与曝光控制，搭建 ISP 调试环境。

---

## 修改平台设备树 (dts)

设备树需根据实际硬件选择对应 dts 文件，例如：`kernel/arch/arm64/boot/dts/hobot/x5-evb.dtsi`。

以下是 X5 EVB 开发板MIPI_CSI0的配置情况:

```dts
//i2c 配置
&i2c4 {
        status = "okay";
};

//lpwm 配置
&lpwm0 {
        status = "okay";
        /* conflict with camera pwd gpio */
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lpwm0_0 &pinctrl_lpwm0_1
                        &pinctrl_lpwm0_2 &pinctrl_lpwm0_3>;
};


// dts： 在对应 vcon node 中设置 gpio，注意 vcon 端口号与 mipi rx 端口号 一 一对应
// vcon0 -- mipi_host0
// ....
// vcon3 -- mipi_host3

&mipi_host0 {
        status = "okay";
        pinctrl-names = "enable", "disable";
        pinctrl-0 = <&pinctrl_sensor0_mclk>; //mclk0
        pinctrl-1 = <&lsio_gpio0_24>;
        snrclk-idx = <0>;  //mclk index
};

&vin_vcon0 {
        status = "okay";
        /* camera sensor
         * reset gpio:	AON_GPIO0_00:	498
         * pwd gpio:	LSIO_GPIO1_00:	347
         */
        pinctrl-names = "default";
        pinctrl-0 = <&aon_gpio_0>;
        gpio_oth = <498>;   //reset gpio
        bus = <4>; //i2c4
        lpwm_chn = <0>;  //open lpwm0 - channel0
};
```

`vcon` 是 X5 用于管理 Sensor 硬件配置的 DTS 节点，需根据硬件连接配置：

- **1. sensor GPIO 配置**
- **2. sensor I2C 配置**
- **3. sensor MCLK 配置**
- **4. sensor LPWM 配置**

### 1. sensor GPIO 配置

- sensor 时序控制相关 GPIO 由 `vin_vcon` 节点中的 `gpio_oth` 描述。
- 当仅需单个 GPIO 控制时，直接指定对应的 GPIO 编号即可。可以配置如 gpio_oth = <498>;
- 当需要多个 GPIO 进行控制时，在 gpio_oth 属性中依次列出所有 GPIO 编号。可以配置如 gpio_oth = <498 386>;
- PinName 管脚和 gpio 编号对应关系的查看的方法参考[hb_gpioinfo 工具介绍](../../linux_development/driver_develop_guide/10-GPIO_Debug_Guide_zh_CN.html#hb-gpioinfo)

```dts
&vin_vcon0 {
  ...
        pinctrl-names = "default";
        pinctrl-0 = <&aon_gpio_0>;
        gpio_oth = <498>;   //reset gpio
  ...
};
```

### 2. sensor I2C 配置

- X5 I2C bus number 需要在 dts vcon 中与 MIPI RX 端口进行绑定。
- 上面的EVB配置使用的I2C4 bus = <4>; 

```dts
&i2c4 {
        status = "okay";
};

&vin_vcon0 {
        status = "okay";
  ...
        bus = <4>; //i2c4
};
```

### 3. sensor MCLK 配置

- MCLK 为 Camera Sensor 主时钟。若由 X5 提供，需在对应 `mipi_host` 节点中配置 pinctrl 与 `snrclk-idx`。
- 注意：MCLK 默认是 GPIO pin，使能 snrclk 或运行 camera 程序时，mipi 驱动会通过 pinctrl 切到 mclk 功能。

```dts
&mipi_host0 {
        status = "okay";
        pinctrl-names = "enable", "disable";
        pinctrl-0 = <&pinctrl_sensor0_mclk>; //mclk0
        pinctrl-1 = <&lsio_gpio0_24>;
        snrclk-idx = <0>;  //mclk index
};
```

### 4. sensor LPWM 配置

- 当 Camera 使用 **Slave Mode** 时需要配置。在 DTS 中使能 LPWM 并在 vcon 中配置 `lpwm_chn`。
- X5 SOC 输出触发时需要在 DTS 中启用 LPWM 功能并配置对应的 lpwm_chn，映射关系如下：

| LPWM控制器 | Channel | 对应 Pinctrl    | 物理引脚        | lpwm_chn |
| :--------- | :------ | :-------------- | :-------------- | :------- |
| LPWM0      | 0       | `pinctrl_lpwm0_0` | LSIO_SPI5_SCLK | 0        |
|            | 1       | `pinctrl_lpwm0_1` | LSIO_SPI5_SSN  | 1        |
|            | 2       | `pinctrl_lpwm0_2` | LSIO_SPI5_MISO | 2        |
|            | 3       | `pinctrl_lpwm0_3` | LSIO_SPI5_MOSI | 3        |
| LPWM1      | 0       | `pinctrl_lpwm1_0` | LSIO_SPI3_SCLK | 4        |
|            | 1       | `pinctrl_lpwm1_1` | LSIO_SPI3_SSN  | 5        |
|            | 2       | `pinctrl_lpwm1_2` | LSIO_SPI3_MISO | 6        |
|            | 3       | `pinctrl_lpwm1_3` | LSIO_SPI3_MOSI | 7        |

```dts
&lpwm0 {
        status = "okay";
        /* conflict with camera pwd gpio */
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lpwm0_0 &pinctrl_lpwm0_1
                        &pinctrl_lpwm0_2 &pinctrl_lpwm0_3>;
};

 &vin_vcon0 {
         status = "okay";
         ...
         lpwm_chn = <0>;  //open lpwm0 - channel0
 };
```

### 5. dts 验证

- dts 配置检查可以通过 `hb_gpioinfo` 进行检查,详细参考[hb_gpioinfo 工具介绍](../../linux_development/driver_develop_guide/10-GPIO_Debug_Guide_zh_CN.html#hb-gpioinfo)
- 下面是 hb_gpioinfo 命令对 管脚复用是否配置检查的结果，查看配置结果是正确的。

```shell
# hb_gpioinfo | grep AON_GPIO_PIN0
line  0:        unnamed output                            AON_GPIO_PIN0         498      aon_gpio_0         10 mA
# hb_gpioinfo | grep LSIO_SPI5_SCLK
line  0:        unnamed input                             LSIO_SPI5_SCLK        347      pinctrl_lpwm0_0    2 mA
# hb_gpioinfo | grep LSIO_SPI3_SCLK
line 24:        unnamed input                             LSIO_SPI3_SCLK        403      lsio_gpio0_24      9 mA
```

dts 配置正确，并且硬件 sensor 正确连接后，手动输入命令满足 sensor 供电和 mclk ，便可以使用 i2cdetect 检测到模组的 i2c 地址。


```shell
echo 498 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio498/direction
echo 0 > /sys/class/gpio/gpio498/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio498/value
# 以 host0/rx0 为例，实际需要换成对应的 mipi rx 端口
# 一般是 24M 时钟输入，以实际为例
echo 24000000 > /sys/class/vps/mipi_host0/param/snrclk_freq
echo 1 > /sys/class/vps/mipi_host0/param/snrclk_en

i2cdetect -y -r 4
```

- 使用 i2cdetect 检测 sensor i2c 地址。如果检测到正确的地址，如下图所示，则表示 dts 配置正确，否则需要检查 dts 配置，或者按照 [i2c 不通](./Camera_sensor_FAQ.html#span-id-i2c-abnormal-i2c) 步骤进行排查。

  ![](./media/Camera_sensor_bringup/5-7-3-1.png)

## 添加 sensor 驱动代码

不同厂家 Sensor 驱动风格不同，需统一适配到 X5 Camera 驱动框架。

### 驱动位置与命名

- **源码路径**：`hbre/camsys/libcam/src/sensor/`
- **部署路径**：编译生成的 `lib<sensor_name>.so` 拷贝到设备 `/usr/hobot/lib/sensor/`
- **文件命名**：`<sensor_name>_utility.c`；**结构体/模块名**：与 `<sensor_name>` 一致（如 sc132gs、os08c10、imx586 等），详见各厂家 bringup。

### sensor_module_t 接口

**1. sensor_module_t 命名规则**

| 项目       | 命名要求                | 示例            |
|------------|-------------------------|-----------------|
| 文件名     | `<sensor_name>_utility.c` | `sc132gs_utility.c` |
| 结构体名   | `<sensor_name>`         | `sc132gs`       |
| module字段 | `<sensor_name>`         | `"sc132gs"`     |

**2. sensor_module_t 接口实现**

驱动需实现 `sensor_module_t`，并实现以下接口：

| 函数接口               | 功能描述                     | 调用时机                             |
|------------------------|------------------------------|--------------------------------------|
| `init`                 | Sensor 初始化、Setting 下发  | hbn_camera_attach_to_vin              |
| `deinit`               | Sensor 去初始化              | hbn_camera_destroy / hbn_camera_detach_from_vin |
| `start`                | Sensor 开流                  | hbn_vflow_start                      |
| `stop`                 | Sensor 关流                  | hbn_vflow_stop                       |
| `power_on`             | Sensor 上电                  | hbn_camera_attach_to_vin              |
| `power_off`            | Sensor 下电                  | hbn_camera_destroy / hbn_camera_detach_from_vin |
| `aexp_gain_control`    | 增益控制                     | ISP 算法调用                         |
| `aexp_line_control`    | 曝光控制                     | ISP 算法调用                         |
| `userspace_control`    | 用户回调控制开关（AE/AWB/AF 等） | 用户控制                             |

**3. 3A 控制**

对于 3A 控制，即userspace_control，X5 系统支持驱动注册和应用层回调两种方式，默认使用应用层回调函数的方式，接口定义如下：

| 函数                 | 功能              | 传入参数 |
| ------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `aexp_gain_control` | sensor 增益控制    | info：sensor 总线信息<br>mode：sensor 运行模式；linear/hdr/pwl<br>again：sensor again 参数，最大4个<br>dgain：sensor dgain 参数，最大4个<br>gain_num：sensor gain 参数个数            |
| `aexp_line_control` | sensor 曝光控制    | info：sensor 总线信息<br>mode：sensor 运行模式；linear/hdr/pwl<br>line：sensor line 参数，最大4个<br>line_num：sensor line 参数个数                                                  |
| `awb_control`       | sensor 端 awb 控制 | info：sensor 总线信息<br>mode：sensor 运行模式；linear/hdr/pwl<br>rgain：sensor rgain<br>bgain：sensor bgain<br>grgain：sensor rrgain<br>gbgain：sensor gbgain                      |
| `userspace_control` | hal 层各类控制开关  | port：sensor 端口号<br>enable：使能用户回调控制开关，默认全部关闭<br>位定义：<br>- `HAL_LINE_CONTROL` 0x00000001<br>- `HAL_GAIN_CONTROL` 0x00000002<br>- `HAL_AWB_CONTROL` 0x00000004 |

### 关键概念

1. **vts/framelength**：每帧总行数（有效行 + 消隐行），不同 sensor 命名可能不同，是计算曝光 / 行时间的核心参数。
2. **lines_per_second**：每秒曝光总行数，可通过 1/每行时间 或 fps×vts 计算。
3. **gain lut 表**：ISP 3A 算法输出的增益索引值与 sensor 硬件寄存器值的映射表，分为 analog gain 和 digital gain 两类，共 256 个控制点（索引 0-255）。这个映射表需要用户自己生成，后面会对不同厂家提供生成方式举例
4. **gain 倍率转换**：所有 gain 索引值（X）对应的实际倍率计算公式为 2^(X/32)，控制曲线为对数型。
5. **digital_gain_max/analog_gain_max**: d_gain/a_gain 最大倍率索引值。
6. **exposure_time_min/exposure_time_max**： 分别为短曝光每帧最小/最大曝光行数。
7. **exposure_time_long_max**：长曝光每帧最大曝光行数，HDR sensor 会用到。
8. **sensor 初始增益曝光值**，供isp ae算法使用，影响前几帧图像的亮度。如果关心前几帧图像亮度需要配置，配置值为sensor setting的寄存器初始值的index值和曝光行数。

    - **analog_gain_init**: sensor analog gain 初始值。可选配置。
    - **digital_gain_init**：sensor digital gain 初始值。可选配置。
    - **exposure_time_init**: sensor 曝光初始值。可选配置。

9. **bayer 格式**：sensor 输出的原始图像像素排列模式，核心参数包括 `bayer_pattern`（像素排列类型，如 RGGB/RCCC/RIrGB/RGIrB）和 `bayer_start`（RGGB 模式的起始像素，如 R/Gr/Gb/B），一般 sensor Spec 中有描述。
    - 在 Bayer 模式中，图像传感器的每个像素点上放置了一个滤光片，只允许特定颜色的光通过，滤光片按照特定的图案排列，以 sc230ai 中描述 `bayer_start` 为 B(0,0) 为例。

 ![](./media/Camera_sensor_bringup/image_20260105-143431.png)


### Gain LUT 表 生成方式

- 为了快速生成 gain_lut 表，X5 提供了gain_table.xlsx 表格，只需要填写 C4 的 增益倍数推导寄存器值的公式，即可快速生成 gain_lut 表
- gain_lut 表一般适用于 OmniVision 的sensor（gain控制一般以整数+小数线性组合）和Sony 的 sensor （gain控制一般以线性公式进行控制）
- SmartSens 的sensor gain控制，一般采用的是 离散档位 + 精细调节,通常查表是最快的，不需要使用gain_table.xlsx 表格生成
- gain_table.xlsx 表格的存放位置在系统 BSP 源码包的 hbre/camsys/libcam/src/sensor 下

### 驱动部署流程

1. 执行 `./bd.sh hbre camsys/libcam` 编译 sensor 库。
2. 将 `out/deploy/hbre/lib/sensor` 下生成的 `lib<sensor_name>.so.*` 拷贝到板端 `/usr/hobot/lib/sensor/`。

**各sensor厂家具体实现（init/start/stop/power、linear_data_init、gain_lut 生成、aexp_gain/line/userspace_control）请参见：**

- [OmniVision Sensor Bring-Up](./OmniVision_sensor_bringup.md)
- [SmartSens Sensor Bring-Up](./SmartSens_sensor_bringup.md)
- [Sony Sensor Bring-Up](./Sony_sensor_bringup.md)

---

## 添加 camera App 代码

参考 BSP 中 `app/samples/platform_samples/vp_sensors`，配置 MIPI、SIF、camera sensor、LPWM、ISP 等。需根据 sensor 分辨率、帧率、数据格式填写`vp_sensor_config_t`。

- **源码路径**：`app/samples/platform_samples/vp_sensors`
- **部署**：将编译得到的 get_vin_data、get_isp_data 等拷贝到设备（如 `/userdata`）测试。编译方法见 [示例开发指南](../../samples/overview.html#id4)。

### vp_sensor_config_t 配置项

vp_sensor_config_t 参数配置 主要包含：mipi 配置、camera sensor 配置、SIF 配置、LPWM 配置 和 ISP 配置，详细参照[数据结构](../../multimedia_development/1-HBN_API_zh_CN.html#id165)。

---

## 添加默认 camera ISP 效果库

- 板端效果库路径：`/usr/hobot/lib/sensor/<sensor_name>_tuning.json`
- 可先拷贝同级目录下同分辨率的 json，将 sensor_name 改为当前 sensor 作为默认效果库。

---

## 板端示例程序运行

- **get_vin_data**：查看 raw 图质量与帧率，确认无严重偏色、与实物颜色一致。用法见 [sample_vin 程序运行方法](../../samples/sample_vin.html#id8)。
- **get_isp_data**：查看 YUV 图像，确认无严重偏色、无反色；精细效果由 ISP 调试。用法见 [sample_isp 程序运行方法](../../samples/sample_isp.html#id8)。

---

## ISP 图像调试预览与 2A 验证

- 在能正常 get_vin_data / get_isp_data 后，可连接 **hbplayer** 预览 YUV，并使用 **tuning_tool** 进行 ISP 调试。详见 [hbplayer 和 tuning_tool 工具使用指南](./Hobot_Player_User_Guide.md)。
- **2A 验证（AE/AWB）**：确认写入 Sensor 的曝光与增益寄存器符合 Spec；将 AE 切为 Manual 后设置 aGain、dGain、integrationTime，通过驱动打印或 i2ctransfer 读寄存器核对。

---

## 小结

- 本文为 Camera 调试的**总览**：准备硬件与软件资源 → 配置 dts → 实现并部署 sensor 驱动 → 配置并运行 App → 准备效果库 → 板端抓 raw/ISP 图 → ISP 预览与 2A 验证。
- 按 sensor 厂家阅读对应分章节可得到连贯、可操作的驱动/App/验证说明；遇到 I2C、MCLK、MIPI、Sensor 等问题可查 [Camera Sensor FAQ](./Camera_sensor_FAQ.md)。
