5.17.6. HDR Sensor Bring-Up
重要
提示 :当接入 HDR Sensor 时,VIN 和 ISP 的 连接 方式 只能 选择 online,由于 online 模式 独占 ISP 资源,所以 仅 支持 1 路。
本文
以 Sony imx415 DOL2 为例,说明 在 X5 平台 上 适配 HDR 模式 Camera Sensor 的 完整 流程。 Sony sensor 的 HDR 实现
方式 是Sensor 在 一个 帧 集 周期 内,交替 输出 不同 曝光 时间 的 图像 行 数据 流程
包括 驱动 实现、App 配置 与 程序验证, 通用 概念 与 dts 配置 请 先 阅读 Camera 调试 指南 。
源码
驱动
接口 :实现 hbre/camsys/libcam/src/sensor/imx415/imx415_utility.c增益
表与 Setting 配置 :hbre/camsys/libcam/src/sensor/imx415/inc/imx415_setting.h(gain_lut、init/stream_on/stream_off 寄存器数组)
5.17.6.1. dts配置
关于dts配置
和 上 电 和sensor的id识别 验证 参考修改 平台 设备树 DOL2 模式
的 dts 配置 与 Linear 模式 一致,无 额外 修改。
5.17.6.2. 驱动
sensor_module_t 与文件命名
文件名:
imx415_utility.c;结构体/模块 名: imx415;库名:libimx415.so.1.0.0,部署到 板端 /usr/hobot/lib/sensor/。需
实现 的 接口:init、deinit、start、stop、power_on、power_off、aexp_gain_control、aexp_line_control、userspace_control。 HDR 模式
与 Linear 模式 共用 同一个 sensor_module_t,通过 sensor_mode区分走 不同 分支。
#ifdef CAMERA_FRAMEWORK_HBN
SENSOR_MODULE_F(imx415, CAM_MODULE_FLAG_A16D8);
sensor_module_t imx415 = {
.module = SENSOR_MNAME(imx415),
#else
sensor_module_t imx415 = {
.module = "imx415",
#endif
.init = sensor_init,
.start = sensor_start,
.stop = sensor_stop,
.deinit = sensor_deinit,
.power_on = sensor_poweron,
.power_off = sensor_poweroff,
.aexp_gain_control = sensor_aexp_gain_control,
.aexp_line_control = sensor_aexp_line_control,
.userspace_control = sensor_userspace_control,
};
power_on
power_on 通过 X5 GPIO 控制 sensor 上电,需
结合 spec 上电 时序。 sensor_poweron 一般
在 sensor_init 中 调用,只 需要 控制 XCLR 即可。 HDR 模式
与 Linear 模式 的 上 电 流程 完全一致,以下 为 imx415 power_on 的 代码 实现:

static int sensor_poweron(sensor_info_t *sensor_info)
{
int gpio, ret = RET_OK;
vin_dbg("%s gpio_num = %d \n", sensor_info->sensor_name, sensor_info->gpio_num);
if(sensor_info->gpio_num > 0) {
for(gpio = 0; gpio < sensor_info->gpio_num; gpio++) {
vin_dbg("%s gpio_pin[%d] = %d \n", sensor_info->sensor_name, gpio, sensor_info->gpio_pin[gpio]);
if(sensor_info->gpio_pin[gpio] != -1) {
ret = vin_power_ctrl(sensor_info->gpio_pin[gpio],
sensor_info->gpio_level[gpio]);
usleep(100 * 1000); // 100ms
ret |= vin_power_ctrl(sensor_info->gpio_pin[gpio],
1 - sensor_info->gpio_level[gpio]);
if(ret < 0) {
vin_err("vin_power_ctrl fail\n");
return -HB_CAM_SENSOR_POWERON_FAIL;
}
usleep(100 * 1000); // 100ms
}
}
}
return ret;
}
power_off
power_off 通过 X5 GPIO 控制 sensor 下电,需
结合 spec 上电 时序。 sensor_poweroff 一般
在 sensor_deinit 中 调用,只 需要 控制 XCLR 即可,以下 为 imx415 power_off 的 代码 实现:

static int sensor_poweroff(sensor_info_t *sensor_info)
{
int gpio, ret = RET_OK;
if(sensor_info->gpio_num > 0) {
for(gpio = 0; gpio < sensor_info->gpio_num; gpio++) {
if(sensor_info->gpio_pin[gpio] != -1) {
ret = vin_power_ctrl(sensor_info->gpio_pin[gpio],
sensor_info->gpio_level[gpio]);
if(ret < 0) {
vin_err("vin_power_ctrl fail\n");
return -HB_CAM_SENSOR_POWEROFF_FAIL;
}
}
}
}
return ret;
}
init
将 sensor 初始化
寄存器 列表 通过 i2c 写 函数 写入 sensor;HDR 模式 使用 DOL2 专用 的 setting 数组。 imx415_dol2_data_init 用于
填充 turning_data 信息。 sensor_init 调用
时机 为 hbn_camera_attach_to_vin。 HDR 模式
通过 sensor_mode == DOL2_M走独立 分支。
static int sensor_init(sensor_info_t *sensor_info)
{
int ret = RET_OK;
int setting_size = 0;
ret = sensor_poweron(sensor_info);
if (ret < 0) {
vin_err("%d : sensor reset %s fail\n", __LINE__, sensor_info->sensor_name);
return ret;
}
switch(sensor_info->sensor_mode) {
case NORMAL_M:
// ... linear 模式初始化(略)...
break;
case DOL2_M:
vin_info("imx415 in dol2/hdr mode\n");
setting_size = sizeof(imx415_init_3840x2160_dol2_4lane_setting) / sizeof(uint32_t) / 2;
ret = vin_write_array(sensor_info->bus_num, sensor_info->sensor_addr, REG_WIDTH,
setting_size, imx415_init_3840x2160_dol2_4lane_setting);
if (ret < 0) {
vin_err("%d : init %s fail\n", __LINE__, sensor_info->sensor_name);
return -HB_CAM_I2C_WRITE_FAIL;
}
ret = imx415_dol2_data_init(sensor_info);
if (ret < 0) {
vin_err("%d : hdr data init %s fail\n", __LINE__, sensor_info->sensor_name);
return -HB_CAM_INIT_FAIL;
}
break;
default:
vin_err("%d not support mode %d\n", __LINE__, sensor_info->sensor_mode);
ret = -HB_CAM_INIT_FAIL;
break;
}
return ret;
}
deinit
deinit 一般
调 用于 sensor 的 反 初始化,直接 调用 power_off 下电 即可。 sensor_deinit 调用
时机 为 hbn_camera_destroy 或者 hbn_camera_detach_from_vin。 HDR 模式
与 Linear 模式 一致。
static int sensor_deinit(sensor_info_t *sensor_info)
{
int ret = RET_OK;
ret = sensor_poweroff(sensor_info);
if (ret < 0) {
vin_err("%d : deinit %s fail\n", __LINE__, sensor_info->sensor_name);
return ret;
}
return ret;
}
start
start 实现
下发 开流 寄存器 0x3000 为 0x00、0x3002 为 0x00,使 sensor 出流。 sensor_start 调用
时机 为 上层 调用 hbn_vflow_start。 HDR 模式
与 Linear 模式 使用 相同 的 stream_on 寄存器。


static int sensor_start(sensor_info_t *sensor_info)
{
int ret = RET_OK;
int setting_size = 0;
switch (sensor_info->sensor_mode) {
case NORMAL_M:
case DOL2_M:
setting_size = sizeof(imx415_stream_on_setting) / sizeof(uint32_t) / 2;
ret = vin_write_array(sensor_info->bus_num, sensor_info->sensor_addr, 2,
setting_size, imx415_stream_on_setting);
if (ret < 0) {
vin_err("start %s fail\n", sensor_info->sensor_name);
return ret;
}
break;
}
return ret;
}
stop
stop 实现
下发 关流 寄存器 0x3000 为 0x01、0x3002 为 0x01,使 sensor 关流。 sensor_stop 调用
时机 为 上层 调用 hbn_vflow_stop。 HDR 模式
与 Linear 模式 使用 相同 的 stream_off 寄存器。
static int sensor_stop(sensor_info_t *sensor_info)
{
int ret = RET_OK;
int setting_size = 0;
setting_size = sizeof(imx415_stream_off_setting) / sizeof(uint32_t) / 2;
vin_info("%s sensor stop\n", sensor_info->sensor_name);
ret = vin_write_array(sensor_info->bus_num, sensor_info->sensor_addr, REG_WIDTH,
setting_size, imx415_stream_off_setting);
if (ret < 0) {
vin_err("start %s fail\n", sensor_info->sensor_name);
return -HB_CAM_I2C_WRITE_FAIL;
}
return ret;
}
ISP 配置与 dol2_data_init
下面

下面

在 DOL2 模式

在 imx415_dol2_data_init 中
需要
从 sensor 读取 VMAX(0x3024-0x3026)和 RHS1(0x3060-0x3062),计算 FSC = VMAX × 2; exposure_time_long_max / exposure_time_max 根据SPEC中 DOL2 公式
计算; gain_lut 使用
turning_data.dol2.again_lut设置
turning_type = 6。
DOL2 曝光
咨询 sensor FAE 后 Toffset 可以
LEF 曝光行数: t_LEF = FSC - SHR0, FSC = VMAX × 2
SEF1 曝光行数: t_SEF1 = RHS1 - SHR1
关键
lines_per_second = FSC * sensor_info->fps(FSC = VMAX × 2)exposure_time_long_max = FSC - (RHS1 + 9)LEF 最大曝光 行 数 exposure_time_max = RHS1 - 9SEF1 最大曝光 行 数 exposure_time_min = 8analog_gain_max = 255与 gain_lut 最大索引 一致 digital_gain_max = 0sensor_data_bayer_fill(..., 10, BAYER_START_GB, BAYER_PATTERN_RGGB);sensor_data_bits_fill(..., 12)
static int imx415_dol2_data_init(sensor_info_t *sensor_info)
{
int ret = RET_OK;
sensor_turning_data_t turning_data;
uint32_t *stream_on = turning_data.stream_ctrl.stream_on;
uint32_t *stream_off = turning_data.stream_ctrl.stream_off;
int val_l = 0, val_m = 0, val_h = 0;
uint32_t Vmax = 0, rhs1 = 0, fsc = 0;
val_l = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_VMAX);
val_m = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_VMAX + 1);
val_h = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_VMAX + 2);
Vmax = ((val_h & 0x0F) << 16) | (val_m << 8) | val_l;
val_l = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_RHS1);
val_m = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_RHS1 + 1);
val_h = hb_vin_i2c_read_reg16_data8(sensor_info->bus_num, sensor_info->sensor_addr, IMX415_RHS1 + 2);
rhs1 = ((val_h & 0x0F) << 16) | (val_m << 8) | val_l;
fsc = Vmax * 2;
memset(&turning_data, 0, sizeof(sensor_turning_data_t));
turning_data.bus_num = sensor_info->bus_num;
turning_data.bus_type = sensor_info->bus_type;
turning_data.port = sensor_info->port;
turning_data.reg_width = sensor_info->reg_width;
turning_data.mode = sensor_info->sensor_mode;
turning_data.sensor_addr = sensor_info->sensor_addr;
strncpy(turning_data.sensor_name, sensor_info->sensor_name,
sizeof(turning_data.sensor_name));
turning_data.sensor_data.turning_type = 6;
turning_data.sensor_data.active_width = sensor_info->width;
turning_data.sensor_data.active_height = sensor_info->height;
turning_data.sensor_data.lines_per_second = fsc * sensor_info->fps;
turning_data.sensor_data.exposure_time_long_max = fsc - (rhs1 + 9);
turning_data.sensor_data.exposure_time_max = rhs1 - 9;
turning_data.sensor_data.exposure_time_min = 8;
turning_data.sensor_data.analog_gain_max = 255;
turning_data.sensor_data.digital_gain_max = 0;
sensor_data_bayer_fill(&turning_data.sensor_data, 10, (uint32_t)BAYER_START_GB, (uint32_t)BAYER_PATTERN_RGGB);
sensor_data_bits_fill(&turning_data.sensor_data, 12);
turning_data.stream_ctrl.data_length = 1;
memcpy(stream_on, imx415_stream_on_setting, sizeof(imx415_stream_on_setting));
memcpy(stream_off, imx415_stream_off_setting, sizeof(imx415_stream_off_setting));
turning_data.dol2.again_lut = malloc(256 * sizeof(uint32_t));
if (turning_data.dol2.again_lut != NULL) {
memset(turning_data.dol2.again_lut, 0xff, 256 * sizeof(uint32_t));
memcpy(turning_data.dol2.again_lut, imx415_gain_lut, sizeof(imx415_gain_lut));
}
ret = ioctl(sensor_info->sen_devfd, SENSOR_TURNING_PARAM, &turning_data);
if (turning_data.dol2.again_lut) {
free(turning_data.dol2.again_lut);
turning_data.dol2.again_lut = NULL;
}
if (ret < 0) {
vin_err("%s sync gain lut ioctl fail %d\n", sensor_info->sensor_name, ret);
return -RET_ERROR;
}
return ret;
}
aexp_gain_control
DOL2 模式
again[0]→ LEF 增益,写入 GAIN_PGC0 (0x3090)again[1]→ SEF1 增益,写入 GAIN_PGC1 (0x3092)
static int sensor_aexp_gain_control(hal_control_info_t *info, uint32_t mode, uint32_t *again, uint32_t *dgain, uint32_t gain_num)
{
const uint16_t AGAIN = GAIN_PGC0;
const uint16_t S_AGAIN = GAIN_PGC1;
char again_reg_value = 0, s_again_reg_value = 0;
int again_index = 0, s_again_index = 0;
if (mode == NORMAL_M) {
if (again[0] >= sizeof(imx415_gain_lut)/sizeof(uint32_t))
again_index = sizeof(imx415_gain_lut)/sizeof(uint32_t) - 1;
else
again_index = again[0];
again_reg_value = (imx415_gain_lut[again_index] >> 0) & 0xFF;
set_gain_registers(info, AGAIN, again_reg_value);
} else if (mode == DOL2_M) {
if (again[0] >= sizeof(imx415_gain_lut)/sizeof(uint32_t))
again_index = sizeof(imx415_gain_lut)/sizeof(uint32_t) - 1;
else
again_index = again[0];
if (again[1] >= sizeof(imx415_gain_lut)/sizeof(uint32_t))
s_again_index = sizeof(imx415_gain_lut)/sizeof(uint32_t) - 1;
else
s_again_index = again[1];
again_reg_value = (imx415_gain_lut[again_index] >> 0) & 0xFF;
s_again_reg_value = (imx415_gain_lut[s_again_index] >> 0) & 0xFF;
set_gain_registers(info, AGAIN, again_reg_value);
set_gain_registers(info, S_AGAIN, s_again_reg_value);
} else {
vin_err(" unsupport mode %d\n", mode);
}
return 0;
}
aexp_line_control
aexp_line_control 在 DOL2 模式
接收 ISP 3A 算法
下发 的 曝光 行 数: line[0](LEF)、line[1](SEF1)将
曝光 行 数 转换 为 SHR0 和 SHR1 寄存器 值 进行
边界 检查和 奇偶 对齐 通过 i2c 下
发给 sensor

DOL2 曝光
SHR0 = FSC - line[0] (LEF, FSC = VMAX × 2)
SHR1 = RHS1 - line[1] (SEF1)
约束:SHR0 为偶数(2n), (RHS1 + 9) ≤ SHR0 ≤ (FSC - 8)
SHR1 为奇数(2n+1), 9 ≤ SHR1 ≤ (RHS1 - 8)
Linear 模式
SHR0 = VMAX - line[0]
约束:8 ≤ SHR0 ≤ (VMAX - 4)
static int sensor_aexp_line_control(hal_control_info_t *info, uint32_t mode, uint32_t *line, uint32_t line_num)
{
uint32_t tmp = 0;
char temp0 = 0, temp1 = 0, temp2 = 0;
int val_l = 0, val_m = 0, val_h = 0;
uint32_t Vmax = 0;
val_l = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_VMAX);
val_m = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_VMAX + 1);
val_h = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_VMAX + 2);
Vmax = ((val_h & 0x0F) << 16) | (val_m << 8) | val_l;
if ((mode == NORMAL_M) || (line_num == 1)) {
int shr0 = Vmax - line[0];
if (shr0 < 8) shr0 = 8;
if (shr0 > (int)(Vmax - 4)) shr0 = Vmax - 4;
tmp = shr0;
temp2 = (tmp >> 16) & 0x0F;
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0 + 2, temp2);
temp1 = (tmp >> 8) & 0xFF;
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0 + 1, temp1);
temp0 = (tmp & 0xFF);
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0, temp0);
} else if (mode == DOL2_M) {
uint32_t rhs1 = 0, fsc = 0;
int shr0 = 0, shr1 = 0;
val_l = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_RHS1);
val_m = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_RHS1 + 1);
val_h = hb_vin_i2c_read_reg16_data8(info->bus_num, info->sensor_addr, IMX415_RHS1 + 2);
rhs1 = ((val_h & 0x0F) << 16) | (val_m << 8) | val_l;
fsc = Vmax * 2;
shr0 = fsc - line[0];
shr1 = rhs1 - line[1];
if (shr1 < 9) shr1 = 9;
if (shr1 > (int)(rhs1 - 8)) shr1 = rhs1 - 8;
if (shr0 < (int)(rhs1 + 9)) shr0 = rhs1 + 9;
if (shr0 > (int)(fsc - 8)) shr0 = fsc - 8;
shr1 |= 0x01; // SHR1 强制为奇数 (2n+1)
shr0 = (shr0 >> 1) << 1; // SHR0 强制为偶数 (2n)
// 写 SHR0 (3字节 LSB first: 0x3050, 0x3051, 0x3052)
tmp = shr0;
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0 + 2, (tmp >> 16) & 0x0F);
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0 + 1, (tmp >> 8) & 0xFF);
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR0, tmp & 0xFF);
// 写 SHR1 (3字节 LSB first: 0x3054, 0x3055, 0x3056)
tmp = shr1;
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR1 + 2, (tmp >> 16) & 0x0F);
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR1 + 1, (tmp >> 8) & 0xFF);
vin_i2c_write8(info->bus_num, 16, info->sensor_addr, IMX415_SHR1, tmp & 0xFF);
} else {
vin_err(" unsupport mode %d\n", mode);
return -1;
}
return 0;
}
userspace_control
这里 sensor_userspace_control 用于 Gain Control 与 Exposure Control 开关。
用于 hbplayer 调试
时 排查 flicker 或 画面 异常,可 开关 HAL_GAIN_CONTROL / HAL_LINE_CONTROL 确认 问题。 HDR 模式
与 Linear 模式 一致。
static int sensor_userspace_control(uint32_t port, uint32_t *enable)
{
vin_info("enable userspace gain control and line control\n");
*enable = HAL_GAIN_CONTROL | HAL_LINE_CONTROL;
return 0;
}
驱动部署
./bd.sh hbre camsys/libcam编译。将
out/deploy/hbre/lib/sensor/libimx415.so.1.0.0拷贝到板端 /usr/hobot/lib/sensor/。
5.17.6.3. App 配置
在
路径 app/samples/platform_samples/vp_sensors/imx415/中为 imx415 DOL2 添加配置。 HTS/VTS 可
从 寄存器 0x3028/0x3029、0x3024~0x3026 读取 或 咨询 Sensor FAE 提供 或者 使用 示波器 测量,测量方法 参考 mipi-参数 确定 mipiclk 一般
询问 Sensor FAE 即可,计算方法 参考 MIPI CLK 其他
的 都 为 通用 配置,参考 文档 数据结构。 进行 配置 即可
vp_sensor 配置文件:dol2_3840x2160_raw10_30fps_4lane.c
配置文件
路径: imx415/dol2_3840x2160_raw10_30fps_4lane.c。配置
结构 体名: imx415_dol2_3480x2160_raw10_30fps_4lane(需在 vp_sensor_config_list 中注册)。 当前
示例 为 RAW10 输出;datatype/format 配置 为 0x2B。
DOL2 模式
MIPI 配置
DOL2 模式
static mipi_config_t imx415_mipi_config = {
.rx_enable = 1,
.rx_attr = {
.phy = 0,
.lane = 4,
.datatype = RAW10,
.fps = 30,
.mclk = 1,
.mipiclk = 7128,
.width = 3840,
.height = 2160,
.linelenth = 6400,
.framelenth = 4700,
.settle = 10,
.channel_num = 2, // DOL2: 2 通道(Linear 为 1)
.channel_sel = {0, 1}, // VC0=LEF, VC1=SEF1
},
.rx_ex_mask = 0x40,
.rx_attr_ex = {
.stop_check_instart = 1,
}
};
与 Linear 模式
channel_num = 2:DOL2 需要接收 VC0 和 VC1 两个 虚拟 通道 的 数据,Linear 为 1 channel_sel = {0, 1}:指定接收 VC0 和 VC1 framelenth:DOL2 与 Linear 的帧 长 不同,需 根据 实际 VMAX 配置 确认
Camera 配置
static camera_config_t imx415_camera_config = {
.name = "imx415",
.addr = 0x1a,
.sensor_mode = DOL2_M, //DOL2 模式(Linear 为 NORMAL_M)
.fps = 30,
.format = RAW10,
.width = 3840,
.height = 2160,
.gpio_enable_bit = 0x01,
.gpio_level_bit = 0x00,
.mipi_cfg = &imx415_mipi_config,
.calib_lname = "imx415_hdr_tuning.json", //HDR 专用 tuning 文件
};
与 Linear 模式
sensor_mode = DOL2_M:决定驱动 init/start/gain/line 走 DOL2 分支 calib_lname:需要 HDR 专用的 tuning 文件
VIN 配置
VIN 配置
static vin_node_attr_t imx415_vin_node_attr = {
.cim_attr = {
.mipi_rx = 0,
.vc_index = 0, // 从 VC0 开始
.ipi_channel = 2, // DOL2: 2 个 IPI 通道(Linear 为 1)
.cim_isp_flyby = 1, // DOL2只支持online 模式
.func = {
.enable_frame_id = 1,
.set_init_frame_id = 0,
.hdr_mode = DOL_2, //通知 ISP 做两帧合成(Linear 为 NOT_HDR)
.time_stamp_en = 0,
},
},
};
关键
| 参数 | Linear 值 | DOL2 值 | 说明 |
|---|---|---|---|
ipi_channel |
1 | 2 | DOL2 需要 2 个 IPI 通道 |
cim_isp_flyby |
0 | 1 | DOL2 通常 |
hdr_mode |
NOT_HDR (0) | DOL_2 (1) | 0: 不 |
VIN 输出
static vin_ochn_attr_t imx415_vin_ochn_attr = {
.ddr_en = 0, //online 模式下为 0
.ochn_attr_type = VIN_BASIC_ATTR,
.vin_basic_attr = {
.format = RAW10,
.wstride = (SENSOR_WIDTH) * 2,
},
};
ISP 配置
ISP 需要
static isp_attr_t imx415_isp_attr = {
.input_mode = PASSTHROUGH_MODE, // online
.sensor_mode = ISP_DOL2_M, // DOL2 合成模式
.tile_mode = 0,
.crop = {
.x = 0, .y = 0,
.h = 2160, .w = 3840,
},
};
关键
| 参数 | Linear 值 | DOL2 值 | 说明 |
|---|---|---|---|
input_mode |
DDR_MODE (2) | PASSTHROUGH_MODE (0) | 与 cim_isp_flyby=1 对应,VIN 和 ISP 间 |
sensor_mode |
ISP_NORMAL_M (0) | ISP_DOL2_M (1) | ISP 内部 |
注意:VIN online ISP 时,
hbn_vflow_bind_vnode的绑定 方式 为 src_out_channel=1, dst_input_channel=0,与 Linear offline 模式的 src_out_channel=0不同。
完整参数汇总
| 配置 |
参数 |
取值 |
|---|---|---|
| 顶层 | config_file |
"dol2_3840x2160_raw10_30fps_4lane.c" |
sensor_name |
"imx415-30fps-4lane-dol2" |
|
chip_id_reg / chip_id |
0x3F12 / 0x0514 | |
sensor_i2c_addr_list |
{0x1A} | |
support_sensor_mode |
{DOL2_M} | |
| MIPI | lane |
4 |
datatype |
RAW10 (0x2B) | |
fps |
30 | |
mipiclk |
7128(Mbps) | |
width / height |
3840 / 2160 | |
linelenth / framelenth |
6400 / 4700 | |
settle |
10 | |
channel_num |
2 | |
channel_sel |
{0, 1} | |
stop_check_instart |
1 | |
| Camera | name / addr |
"imx415" / 0x1A |
sensor_mode |
DOL2_M | |
format |
RAW10 | |
gpio_enable_bit / gpio_level_bit |
0x01 / 0x00 | |
calib_lname |
"imx415_hdr_tuning.json" |
|
| VIN | mipi_rx |
0 |
vc_index |
0 | |
ipi_channel |
2 | |
cim_isp_flyby |
1(online) | |
hdr_mode |
DOL_2 | |
mclk_freq (vin_attr_ex) |
24000000 | |
| VIN 输出 | ddr_en |
0(online 模式) |
wstride |
SENSOR_WIDTH × 2(RAW10 为 ×2) | |
| ISP 输入 | input_mode |
PASSTHROUGH_MODE |
sensor_mode |
ISP_DOL2_M | |
crop |
x=0, y=0, w=3840, h=2160 | |
input_fmt |
FRM_FMT_RAW | |
input_bit_width |
10 | |
| ISP 输出 | output_fmt |
FRM_FMT_NV12 |
output_bit_width |
8 | |
ddr_en |
1 |
5.17.6.4. 程序验证
get_vin_data:确认 raw 图
无 严重 偏色、帧 率 符合 配置。DOL2 模式 下会 有 两个 channel 的 数据。 get_isp_data:准备
imx415_hdr_tuning.json(可拷贝 同 分辨率 hdr json 并 改 sensor_name),确认 ISP 合成 后 的 YUV 图像 正常,亮暗 区域 细节 应比 Linear 模式 更 丰富。 hbplayer:连接
板端 预览 短帧 和 长 帧 以及YUV数据,见 hbplayer 和 tuning_tool 工具 使用指南 。tuning_tool:使用 tuning_tool 连接 hbplayer 后,输入
命令 e,配置 Manual AE,分别 设置 LEF 和 SEF1 的 aGain、integrationTime,看 驱动 打印 核对 SHR0 (0x3050~0x3052)、SHR1 (0x3054~0x3056)、GAIN_PGC0 (0x3090)、GAIN_PGC1 (0x3092) 与 spec 一致,ISP 增益 限制 可 在 imx415_hdr_tuning.json 中 配置 以便 自测。
常见问题