全志 v851s sensor驱动曝光增益逻辑查表法示例

说明

        之前的文章有提到,关于sensor 的曝光增益逻辑,如果模组厂提供了完整的参考代码,可以无痛使用的话,就能很方便移植。但如果模组厂提供的参考代码不合适,或者只提供了Excel表格,这时候曝光增益逻辑函数就需要自己去写一下。

        一般模组厂提供了Excel表格,那曝光增益逻辑基本上都是查表法,表格一列是sensor 的增益,另一列是具体gain 对应的增益寄存器的值,我们所实现的曝光增益逻辑函数的功能,就是根据传进来的实际gain值,查表得出寄存器值,然后写进去寄存器就好了。

        然后就是,如果提供的参数需要取整的话,做一些取整操作,基本就这些。

示例

        示例使用 ov02b10 驱动,模组厂提供的曝光增益表和参考代码是这样的:

我这边使用了第二个表格,从gain值得到reg的值,右侧的计算函数没什么必要,实际就是 reg = gain * 16 ,直接使用查表法。另外就是左侧增益值范围 1~15.5,中间有不少的小数,做了一下取整操作,取整幅度乘以1024,具体代码实现如下,也是参考其他sensor驱动写的:

static int setSensorGain(struct v4l2_subdev *sd, int gain)
{
#define ISP_BASE_GAIN        16      //驱动的增益最小值为  1 << 4 = 16
#define SENSOR_BASE_GAIN    1024           //取整步距 
#define SENSOR_MAX_GAIN     15872   //换算得出的最大增益值  15.5*1024
    int i;
    uint32_t temp_gain = 0;
    int32_t gain_index;
    int isp_gain = gain;
    int sensor_gain = 0;
    
    struct sensor_info *info = to_state(sd);
    
    sensor_gain = isp_gain < ISP_BASE_GAIN ? ISP_BASE_GAIN : isp_gain;  //限定增益数值,最小值以下按最小值处理
    sensor_gain = sensor_gain * SENSOR_BASE_GAIN / ISP_BASE_GAIN;       //换算增益值,除以16,乘以1024,得出查表第一列的值

    if (SENSOR_MAX_GAIN < sensor_gain)
        sensor_gain = SENSOR_MAX_GAIN;   //超过最大值的按最大值处理
    
    
    uint16_t OV02B10_AGC_Param[][2] ={
    {1        *1024,  0x10},
    {1.0625 *1024,  0x11},
    {1.125  *1024,  0x12},
    {1.1875 *1024,  0x13},
    {1.25   *1024,  0x14},
    {1.3125 *1024,  0x15},
    {1.375  *1024,  0x16},
    {1.4375 *1024,  0x17},
    {1.5    *1024,  0x18},
    {1.5625 *1024,  0x19},
    {1.625  *1024,  0x1A},
    {1.6875 *1024,  0x1B},
    {1.75   *1024,  0x1C},
    {1.8125 *1024,  0x1D},
    {1.875  *1024,  0x1E},
    {1.9375 *1024,  0x1F},
    {2        *1024,  0x20},
    {2.125  *1024,  0x22},
    {2.25   *1024,  0x24},
    {2.375  *1024,  0x26},
    {2.5    *1024,  0x28},
    {2.625  *1024,  0x2A},
    {2.75   *1024,  0x2C},
    {2.875  *1024,  0x2E},
    {3        *1024,  0x30},
    {3.125  *1024,  0x32},
    {3.25   *1024,  0x34},
    {3.375  *1024,  0x36},
    {3.5    *1024,  0x38},
    {3.625  *1024,  0x3A},
    {3.75   *1024,  0x3C},
    {3.875  *1024,  0x3E},
    {4        *1024,  0x40},
    {4.25   *1024,  0x44},
    {4.5    *1024,  0x48},
    {4.75   *1024,  0x4C},
    {5        *1024,  0x50},
    {5.25   *1024,  0x54},
    {5.5    *1024,  0x58},
    {5.75   *1024,  0x5C},
    {6        *1024,  0x60},
    {6.25   *1024,  0x64},
    {6.5    *1024,  0x68},
    {6.75   *1024,  0x6C},
    {7        *1024,  0x70},
    {7.25   *1024,  0x74},
    {7.5    *1024,  0x78},
    {7.75   *1024,  0x7C},
    {8        *1024,  0x80},
    {8.5    *1024,  0x88},
    {9        *1024,  0x90},
    {9.5    *1024,  0x98},
    {10        *1024,  0xA0},
    {10.5   *1024,  0xA8},
    {11        *1024,  0xB0},
    {11.5   *1024,  0xB8},
    {12        *1024,  0xC0},
    {12.5   *1024,  0xC8},
    {13        *1024,  0xD0},
    {13.5   *1024,  0xD8},
    {14        *1024,  0xE0},
    {14.5   *1024,  0xE8},
    {15        *1024,  0xF0},
    {15.5   *1024,  0xF8},
};

    if (sensor_gain < SENSOR_BASE_GAIN)
        sensor_gain = SENSOR_BASE_GAIN;
    if (sensor_gain > SENSOR_MAX_GAIN)
        sensor_gain = SENSOR_MAX_GAIN;        

    uint32_t total_cnt = (sizeof(OV02B10_AGC_Param)/sizeof(OV02B10_AGC_Param[0]));
    for (gain_index = 0; gain_index < total_cnt -1; gain_index++)  //对比查表得出对应增益的寄存器数值
    {
        if((sensor_gain >= OV02B10_AGC_Param[gain_index][0])&&(sensor_gain <= OV02B10_AGC_Param[gain_index+1][0]))
        {
            if((sensor_gain-OV02B10_AGC_Param[gain_index][0]) <= (OV02B10_AGC_Param[gain_index+1][0]-sensor_gain))
                temp_gain = OV02B10_AGC_Param[gain_index][1];
            else
                temp_gain = OV02B10_AGC_Param[gain_index+1][1];
            break;
        }
    }

    sensor_dbg("OV02B10_AGC_Param[gain_index][1] = 0x%x, temp_gain = 0x%x, sensor_gain = 0x%x, total_cnt = %d\n",
        OV02B10_AGC_Param[gain_index][1], temp_gain, sensor_gain, total_cnt);
        
    sensor_write(sd, 0xfd, 0x01);    //将寄存器数值写入寄存器
    sensor_write(sd, 0x22, temp_gain);
    sensor_write(sd, 0xfe, 0x02);
    info->gain = temp_gain;

    return 0;
}

以上代码提供一种参考的思路,有问题还请指正,一键三连,感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值