(仅作记录)
1. 平台:rk3588
2. sensor:imx415
3. 配置所需文件:
IMX415_AppNote_DOL_E_Rev1.0
IMX415-AAQR-C_TechnicalDatasheet_E_Rev0.4
HDR功能,其曝光增益和线性模式不一样,有各种的计算公式以及逻辑条件限制,具体看datasheet里面的restriction。
以HDR2为例,首先看下datasheet里的 restriction 如下图所示;
上面那两张图就是配置hdrae所需要的,此外可以先理解一下RHS1 SHR0 SHR1,看下图
可以如下简单理解:
FSC = vts
SHR0= FSC - l_exp_time ;
RHS1= s_exp_time + SHR1 ;
接下来看下代码,根据图中的限制条件,一一列出;其实也挺简单的。
/* Restrictions
* FSC = 2 * VMAX and FSC should be 4n;
* exp_l = FSC - SHR0 + Toffset;
* exp_l should be even value;
*
* SHR0 = FSC - exp_l + Toffset;
* SHR0 <= (FSC -8);
* SHR0 >= RHS1 + 9;
* SHR0 should be 2n;
*
* exp_s = RHS1 - SHR1 + Toffset;
* exp_s should be even value;
*
* RHS1 < BRL * 2;
* RHS1 <= SHR0 - 9;
* RHS1 >= SHR1 + 8;
* SHR1 >= 9;
* RHS1(n+1) >= RHS1(n) + BRL * 2 -FSC + 2;
*
* SHR1 should be 2n+1 and RHS1 should be 4n+1;
*/
/* The HDR mode vts is double by default to workaround T-line */
fsc = imx415->cur_vts;
shr0 = fsc - l_exp_time;
if (imx415->cur_mode->height == 2192) {
rhs1_max = min(RHS1_MAX_X2(BRL_ALL), ((shr0 - 9u) / 4 * 4 + 1));
rhs1_min = max(SHR1_MIN_X2 + 8u, rhs1_old + 2 * BRL_ALL - fsc + 2);
} else {
rhs1_max = min(RHS1_MAX_X2(BRL_BINNING), ((shr0 - 9u) / 4 * 4 + 1));
rhs1_min = max(SHR1_MIN_X2 + 8u, rhs1_old + 2 * BRL_BINNING - fsc + 2);
}
rhs1_min = (rhs1_min + 3) / 4 * 4 + 1;
rhs1 = (SHR1_MIN_X2 + s_exp_time + 3) / 4 * 4 + 1;/* shall be 4n + 1 */
dev_dbg(&client->dev,
"line(%d) rhs1 %d, rhs1 min %d rhs1 max %d\n",
__LINE__, rhs1, rhs1_min, rhs1_max);
if (rhs1_max < rhs1_min) {
dev_err(&client->dev,
"The total exposure limit makes rhs1 max is %d,but old rhs1 limit makes rhs1 min is %d\n",rhs1_max, rhs1_min);
return -EINVAL;
}
rhs1 = clamp(rhs1, rhs1_min, rhs1_max);
dev_dbg(&client->dev,
"line(%d) rhs1 %d, short time %d rhs1_old %d, rhs1_new %d\n",
__LINE__, rhs1, s_exp_time, rhs1_old, rhs1);
rhs1_old = rhs1;
if (rhs1 - s_exp_time <= SHR1_MIN_X2) {
shr1 = SHR1_MIN_X2;
s_exp_time = rhs1 - shr1;
} else {
shr1 = rhs1 - s_exp_time;
}
if (shr0 < rhs1 + 9)
shr0 = rhs1 + 9;
else if (shr0 > fsc - 8)
shr0 = fsc - 8;
注释:
rhs1_min = (rhs1_min + 3) / 4 * 4 + 1;
rhs1 = (SHR1_MIN_X2 + s_exp_time + 3) / 4 * 4 + 1;/* shall be 4n + 1 */
像rhs1_min + 3主要是4对齐,建议往大的对齐,例如 (11+3)/4*4+1=12+1; 11/4*4+1=8+1;
所以11当然是往大的12对齐而不是8.
提一下线性模式的曝光配置,不同sensor,写法不一样的;有的sensor是直接通过shr0来设置曝光的(shr寄存器);有的直接像曝光寄存器写入曝光值。如下分别用imx335和imx378为例
case V4L2_CID_EXPOSURE:
/* 4 least significant bits of expsoure are fractional part */
ret = imx577_write_reg(imx577->client,
IMX577_REG_EXPOSURE,
IMX577_REG_VALUE_16BIT,
ctrl->val);
break;
case V4L2_CID_EXPOSURE:
if (imx335->cur_mode->hdr_mode != NO_HDR)
return ret;
shr0 = imx335->cur_vts - ctrl->val;
ret = imx335_write_reg(imx335->client, IMX335_LF_EXPO_REG_L,
IMX335_REG_VALUE_08BIT,
IMX335_FETCH_EXP_L(shr0));
ret |= imx335_write_reg(imx335->client, IMX335_LF_EXPO_REG_M,
IMX335_REG_VALUE_08BIT,
IMX335_FETCH_EXP_M(shr0));
ret |= imx335_write_reg(imx335->client, IMX335_LF_EXPO_REG_H,
IMX335_REG_VALUE_08BIT,
IMX335_FETCH_EXP_H(shr0));
dev_dbg(&client->dev, "set exposure(shr0) %d = cur_vts(%d) - val(%d)\n",
shr0, imx335->cur_vts, ctrl->val);
break;
以上需要自己去体会哈!