【Camera专题】Camera驱动源码全解析_下

2020-03-25  本文已影响0人  c枫_撸码的日子

1、手把手撸一份驱动 到 点亮 Camera
2、Camera dtsi 完全解析
3、Camera驱动源码全解析上
4、Camera驱动源码全解析下
上篇文章分析了C文件函数的实现,本文继续分析h文件的配置信息。

推荐文章:
MIPI CSI2学习(一):说一说MIPI CSI2
高通camera驱动分析

一、h文件中配置信息分析

1.sensor增益的宏定义

/* OVXXX Regs */
#define OVXXX_DATA_PEDESTAL            0x40 /* 10bit value */

#define OVXXX_DIG_GAIN_GLOBAL_ADDR     0x350a //数字增益地址

#define OVXXX_MIN_AGAIN_REG_VAL        0x100 /* 1.0x */

/* OVXXX_MAX_AGAIN_REG_VAL is 0x7FF, 2047, 15.99x
 * use max analog again 15.5x here
  模拟增益
 */
#define OVXXX_MAX_AGAIN_REG_VAL       0xF80 /* 15.5x */

#define OVXXX_MIN_DGAIN_REG_VAL        0x400 /* 1.0x */
#define OVXXX_MAX_DGAIN_REG_VAL        0x800 /* 2.0x */

#define OVXXX_MAX_DGAIN_DECIMATOR      1024

/* OVXXX FORMULAS */
#define OVXXX_MIN_AGAIN    1.0
#define OVXXX_MAX_AGAIN    15.0

#define OVXXX_MIN_DGAIN    (OVXXX_MIN_DGAIN_REG_VAL / 1024)
#define OVXXX_MAX_DGAIN    (OVXXX_MAX_DGAIN_REG_VAL / 1024)

#define OVXXX_MIN_GAIN (OVXXX_MIN_AGAIN * OVXXX_MIN_DGAIN)
#define OVXXX_MAX_GAIN (OVXXX_MAX_AGAIN * OVXXX_MAX_DGAIN)

#define OVXXX_MAX_LINECOUNT (65535-8)

参照sensor规格书或者咨询fae,配置:

  1. sensor数字增益最大和最小值
  2. sensor模拟增益最大和最小值
  3. sensor最大曝光lince_cnt

2.Sensor寄存器控制

2.1 sensor帧的输出和关闭

#define START_REG_ARRAY \
{ \
   {0x0100, 0x01, 0x00}, \
}
#define STOP_REG_ARRAY \
{ \
   {0x0100, 0x00, 0x00}, \
}
/* Sensor Handler */
static sensor_lib_t sensor_lib_ptr =
{
  .start_settings =
  {
    .reg_setting_a = START_REG_ARRAY,
    .addr_type = CAMERA_I2C_WORD_ADDR,
    .data_type = CAMERA_I2C_BYTE_DATA,
    .delay = 0,
  },
  .stop_settings =
  {
    .reg_setting_a = STOP_REG_ARRAY,
    .addr_type = CAMERA_I2C_WORD_ADDR,
    .data_type = CAMERA_I2C_BYTE_DATA,
    .delay = 0,
  },
}

sensor以流的方式 输出帧.

2.2 开启sensor 端的group 功能

//开启
#define GROUPON_REG_ARRAY \
{ \
    {0x3208, 0x00, 0x00}, \
}
//关闭
#define GROUPOFF_REG_ARRAY \
{ \
    {0x3208, 0x10, 0x00}, \
    {0x3208, 0xa0, 0x00}, \
}

  .groupon_settings =
  {
    .reg_setting_a = GROUPON_REG_ARRAY,
    .addr_type = CAMERA_I2C_WORD_ADDR,
    .data_type = CAMERA_I2C_BYTE_DATA,
    .delay = 0,
  },
  .groupoff_settings =
  {
    .reg_setting_a = GROUPOFF_REG_ARRAY,
    .addr_type = CAMERA_I2C_WORD_ADDR,
    .data_type = CAMERA_I2C_BYTE_DATA,
    .delay = 0,
  },

开启sensor 端的group 功能,将曝光(line),gain等打包,保证在同一帧进去生效

2.3 sensor嵌入式数据

/* Sensor Handler */
static sensor_lib_t sensor_lib_ptr =
{
  .embedded_data_enable_settings =
  {
    .reg_setting_a = {},
    .addr_type = 0,
    .data_type = 0,
    .delay = 0,
  },
  .embedded_data_disable_settings =
  {
    .reg_setting_a = {},
    .addr_type = 0,
    .data_type = 0,
    .delay = 0,
  },
}

2.4 sensor初始化相关寄存器

#define INIT_0_REG_ARRAY \
{ \
    {0x0103, 0x01, 0x10}, \
    {0x0303, 0x01, 0x00}, \
···
}
/* Sensor Handler */
static sensor_lib_t sensor_lib_ptr =
{
  .init_settings_array =
  {
    .reg_settings =
    {
      {
        .reg_setting_a = INIT_0_REG_ARRAY,
        .addr_type = CAMERA_I2C_WORD_ADDR,
        .data_type = CAMERA_I2C_BYTE_DATA,
        .delay = 0,
      },
    },
    .size = 1,
  },
}

2.5 sensor分辨率相关寄存器

 /* 2400W@30fps 1120Mbps/lane */
#define RES0_REG_ARRAY \
{ \
    {0x0303, 0x01, 0x00}, \
    {0x0305, 0x46, 0x00}, \
···
}

 /* 1200W@30fps 1120Mbps/lane */
#define RES1_REG_ARRAY \
{ \
    {0x0303, 0x01, 0x00}, \
    {0x0305, 0x46, 0x00}, \
···
}
  .res_settings_array =
  {
    .reg_settings =
    {
      /* Res 0 */
      {
        .reg_setting_a = RES0_REG_ARRAY,
        .addr_type = CAMERA_I2C_WORD_ADDR,
        .data_type = CAMERA_I2C_BYTE_DATA,
        .delay = 0,
      },
      /* Res 1 */
      {
        .reg_setting_a = RES1_REG_ARRAY,
        .addr_type = CAMERA_I2C_WORD_ADDR,
        .data_type = CAMERA_I2C_BYTE_DATA,
        .delay = 0,
      },
    .size = 2,
  },

以上的sensor寄存器配置一般有fae厂商提供,驱动工程师尽可能的掌握相关寄存器代表的含义。
如控制宽高、帧率、曝光等等寄存器

3.sensor_slave_info结构体分析

3.1 Sensor slave 信息

  .sensor_slave_info =
  {
    .sensor_name = "OXXXX",
    .slave_addr = 0x6c,
    .i2c_freq_mode = SENSOR_I2C_MODE_FAST,
    .addr_type = CAMERA_I2C_WORD_ADDR,//16个字节
    .sensor_id_info =
    {
      .sensor_id_reg_addr = 0x300b,
      .sensor_id = 0x0D42,
    },
     .power_setting_array =
    {
      .power_setting_a =
      {
        ···
      }
      .size = 7,
      .power_down_setting_a =
      {
       ···
      }
      .size = 7,
   },   

我们只用到16位,因此
sensor_id_reg_addr = 0x300b,
sensor_id = 0x0D42,

3.2 Sensor 输出参数

  .sensor_output =
  {
    .output_format = SENSOR_BAYER,
    .connection_mode = SENSOR_MIPI_CSI,
    .raw_output = SENSOR_10_BIT_DIRECT,
    .filter_arrangement = SENSOR_BGGR,
  },

3.3 sensor 宽高寄存器地址

  .output_reg_addr =
  {
    .x_output = 0x3808,
    .y_output = 0x380A,
    .line_length_pclk = 0x380C,
    .frame_length_lines = 0x380E,
  },

曝光时间以行长为单位; PCLK以Hz为单位;
行长以周期数为单位,帧长以行长数为单位;其中周期数就是频率
T 周期以ms为单位;
f 频率以Hz为单位;
f = 1 / T;

3.4 曝光寄存器地址

  .exp_gain_info =
  {
    .coarse_int_time_addr = 0x3500,
    .global_gain_addr = 0x3508,
    .vert_offset = 8,
  },

3.5 曝光信息

  .aec_info =
  {
    .min_gain = 1.0,
    .max_gain = 15.5,
    .max_analog_gain = 15.5,
    .max_linecount = 0xffff-8,
  },

比如这里又3个寄存器,每个寄存器是8bit:
max_linecount = 0x ff ff -8


3.6 跳帧设置

  .sensor_num_frame_skip = 2,
  .sensor_num_HDR_frame_skip = 2,
  .sensor_max_pipeline_frame_delay = 2,
  .sensor_num_fast_aec_frame_skip = 2,

3.7 sensor_property

  .sensor_property =
  {
    .pix_size = 1.0,
    .sensing_method = SENSOR_SMETHOD_ONE_CHIP_COLOR_AREA_SENSOR,
    .crop_factor = 1.0,
  },

暂时没弄清楚

3.8 有效像素

  .pixel_array_size_info =
  {
    .active_array_size =
    {
      .width =  3264,
      .height = 2448,
    },
    .left_dummy = 0,
    .right_dummy = 0,
    .top_dummy = 0,
    .bottom_dummy = 0,
  },

3.9 sensor暗电流信息

  .color_level_info =
  {
    .white_level = 1023,
    .r_pedestal = 64,
    .gr_pedestal = 64,
    .gb_pedestal = 64,
    .b_pedestal = 64,
  },

这里指的是暗电流值,
一般来说 raw8 都是 16, raw10为 16x4=64, raw12 =16x4x4

3.10 sensor 数据流信息


  .sensor_stream_info_array =
  {
    .sensor_stream_info =
    {
      {
        .vc_cfg_size = 1,
        .vc_cfg =
        {
          {
            .cid = 0,
            .dt = CSI_RAW10,
            .decode_format = CSI_DECODE_10BIT
          },
        },
        .pix_data_fmt =
        {
          SENSOR_BAYER,
        },
      },
    },
    .size = 1,
  },

传感器可以流式传输许多不同的数据类型(DT)
该数据被包装在不同的流中。 在一个流中,可以有一个或多个不同的DT。 一种虚拟通道(VC)分配给每个流。 DT和VC的组合应为唯一,并分配了一个通道ID(CID)。
有关如何指定CID的要求/限制。 当前的MIPI CSI_Rx支持四个VC,每个VC最多可以有四个CID,如下表所示。

#define CSI_EMBED_DATA        0x12
#define CSI_RESERVED_DATA_0   0x13
#define CSI_YUV422_8          0x1E
#define CSI_RAW8              0x2A
#define CSI_RAW10             0x2B
#define CSI_RAW12             0x2C
#define CSI_RAW14             0x2D
#define CSI_DPCM6             0x32
#define CSI_DPCM8             0x30
#define CSI_DECODE_6BIT           0
#define CSI_DECODE_8BIT           1
#define CSI_DECODE_10BIT          2
#define CSI_DECODE_12BIT          3
#define CSI_DECODE_14BIT          8
#define CSI_DECODE_DPCM_10_8_10   5
#define CSI_DECODE_DPCM_10_6_10   4
147typedef enum {
148  SENSOR_BAYER,
149  SENSOR_YCBCR,
150  SENSOR_GREY,
151  SENSOR_META,
152  SENSOR_BAYER_SVHDR,
153  SENSOR_BAYER_SVHDR_SUBFRAME
154} sensor_output_format_t;

4.测试图案配置

传感器可能具有内置的pattern generator。 通过设置专用寄存器,传感器可以将生成的图案输出。

.test_pattern_info =
  {
    .test_pattern_settings =
    {
      {
        .mode = SENSOR_TEST_PATTERN_OFF,//关闭测试模式
        .settings =
        {
          .reg_setting_a =
          {
            {0x5080, 0x00, 0x00},
          },
          .addr_type = CAMERA_I2C_WORD_ADDR,
          .data_type = CAMERA_I2C_BYTE_DATA,
          .delay = 0,
        }
      },
      {
        .mode = SENSOR_TEST_PATTERN_COLOR_BARS,//color bar 测试
        .settings =
        {
          .reg_setting_a =
          {
            {0x5080, 0x80, 0x00},
          },
          .addr_type = CAMERA_I2C_WORD_ADDR,
          .data_type = CAMERA_I2C_BYTE_DATA,
          .delay = 0,
        },
      },
    },
      {
        .mode = SENSOR_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY,
        .settings =
        {
          .reg_setting_a =
          {
            {0x5080, 0x84, 0x00},
          },
          .addr_type = CAMERA_I2C_WORD_ADDR,
          .data_type = CAMERA_I2C_BYTE_DATA,
          .delay = 0,
        },
      },
    },
    .size = 3,
//对于纯色测试图案模式,我们可以设置帧的颜色。
    .solid_mode_addr =
    {
      .r_addr = 0,
      .gr_addr = 0,
      .gb_addr = 0,
      .b_addr = 0,
    },
  },

当出现图像异常时,可以使用此功能看看sensor本身输出是否有问题。


5. sensor分辨率

  .out_info_array =
  {
    .out_info =
    {
     /* Res 0 */
     {
      .x_output = 3264,
      .y_output = 2448,
      .line_length_pclk = 1176,
      .frame_length_lines = 3196,
      .vt_pixel_clk = 112754800,
      .op_pixel_clk = 448000000,
      .binning_factor = 1,
      .binning_method = 0,
      .min_fps = 7.5,
      .max_fps = 30,
      .mode = SENSOR_DEFAULT_MODE,
      .offset_x = 0,
      .offset_y = 0,
      .scale_factor = 1.000,
      .is_pdaf_supported = 1,
      .data_rate = 1120000000ULL * 4,
     },
SENSOR_DEFAULT_MODE – Normal sensor modes – preview, video, snapshot, ZSL, etc.
SENSOR_HFR_MODE – High frame rate mode – modes with a frame rate greater than 30 fps are
used for high-speed video recording.
SENSOR_HDR_MODE – High Dynamic Range (HDR) mode – use for HDR video and image
recording.

6.CSI参数配置

  .csi_params =
  {
    .lane_cnt = 4,
    .settle_cnt = 0x14,
    .is_csi_3phase = 0,
  },

CSI :Camera Serial Interface 定义了一个位于处理器和摄像模组之间的高速串行接口

为使CSI_Tx(传感器)和CRI_Rx(设备)正常工作,需要一段时间它们之间需要同步。
此时间在此处设置为计时器时钟滴答数。 它必须介于公式计算的MIN和MAX值之间
MIN [Settle count * T(Timer clock)] > T(HS_SETTLE)_MIN
MAX [Settle count * T(Timer clock)] < T(HS-PREPARE)+T(HS_ZERO) - 4*T(Timer clock)

settle_cnt(即稳定计数)– 必须根据传感器输出特性配置该值,以确保传感器的 PHY
发送器与 MSM 的 PHY 接收器无障碍同步。
对于 28 nm 以及更小的 MSM 芯片,使用以下公式计算稳定计数:
settle_cnt = T(HS_SETTLE)_avg /T(TIMER_CLK),
其中 T(HS_SETTLE)_avg = (T(HS_SETTLE)_min + T(HS_SETTLE)_max) / 2,如传
感器数据表所指示

7. CSID configuration

 .csid_lut_params_array =
  {
    .lut_params =
    {
      /* Res 0 */
      {
        .num_cid = 1,
        .vc_cfg_a =
        {
          {
            .cid = 0,
            .dt = CSI_RAW10,
            .decode_format = CSI_DECODE_10BIT
          },
        },
      },
    .size=1,
  },

8.sensor 裁剪配置

  .crop_params_array =
  {
    .crop_params =
    {
      /* Res 0 */
      {
        .top_crop = 0,
        .bottom_crop = 0,
        .left_crop = 0,
        .right_crop = 0,
      },
}

9.曝光函数配置

  .exposure_func_table =
  {
    .sensor_calculate_exposure = sensor_calculate_exposure,
    .sensor_fill_exposure_array = sensor_fill_exposure_array,
  },

10.meta data配置

  .meta_data_out_info_array =
  {
    .meta_data_out_info =
    {
      {
        .width = 0,//宽
        .height = 0,//高
        .stats_type = 0,//数据类型
      },
    },
    .size = 0,
  },

11. HDR AWB 配置

  .awb_func_table =
  {
    .sensor_fill_awb_array = 0,
    .awb_table_size = 0,
  },

如果sensor可以直接流式传输HDR帧,该函数才有用。

12 sensor rolloff 设置

  .rolloff_config =
  {
    .enable = FALSE,
    .full_size_info =
    {
      .full_size_width = 0,
      .full_size_height = 0,
      .full_size_left_crop = 0,
      .full_size_top_crop = 0,
    },
  },

这里的 rolloff compensations = Lens Shading Correction (LSC)
有些sensor可以自己内部做lsc补偿。rolloff_config就是用了配置sensor的这些信息。

注意:如果你使用了sensor LSC补偿,平台端 lsc补偿就要关闭,否则双倍补偿,可能会造成图片失真。

12.曝光延迟配置

   .app_delay = {
    [SENSOR_DELAY_EXPOSURE] = 0,
    [SENSOR_DELAY_ANALOG_SENSOR_GAIN] = 0,
    [SENSOR_DELAY_DIGITAL_SENSOR_GAIN] = 0,
    [SENSOR_DELAY_ISP_GAIN] = 0,
  },

typedef enum {
SENSOR_DELAY_EXPOSURE, /* delay for exposure/
SENSOR_DELAY_ANALOG_SENSOR_GAIN, /
delay for sensor analog gain/
SENSOR_DELAY_DIGITAL_SENSOR_GAIN, /
delay for sensor digital gain/
SENSOR_DELAY_ISP_GAIN, /
delay for sensor ISP (error) gain*/
SENSOR_DELAY_MAX,
} sensor_delay_type_t;

SENSOR_DELAY_EXPOSURE – Sets the exposure of frame N at frame N + delay
SENSOR_DELAY_ANALOG_SENSOR_GAIN – Sets the analog gain register at frame N + delay
SENSOR_DELAY_DIGITAL_SENSOR_GAIN – Sets the digital gain register at frame N + delay
SENSOR_DELAY_ISP_GAIN – Passes the isp digital gain to the isp module at frame N + delay

如果出现ae闪烁问题,可以尝试修改延迟,让gain和expose同步。

13. ADC readout time

  .adc_readout_time = 0,

This is the readout time (in nanoseconds) of the sensor’s analog-to-digital converter. Usually it is
the minimum line time when the sensor is running at the maximum pixel clock.
NOTE: This is the sensor module’s own information. Refer to the sensor vendor for more information

14.噪声系数

  .noise_coeff = {
    .gradient_S = 3.738032e-06,
    .offset_S = 3.651935e-04,
    .gradient_O = 6.396835e-11,
    .offset_O = -2.968624e-04,
  },

noise_coeff 小波里用来定义噪声的模板
噪声系数模型: N(x) = sqrt(Sx + O)

这些参数一般由tunning团队修改。

15.PDAF 配置

  .pdaf_config =
  {
#ifndef FLIP_MIRROR
    #include "xxxx_pdaf.h"
#else
   #include "xxxx_pdaf_flip_mirror.h"
#endif
  },

16.XML配置

关于角度

sensor_init_xml_probe
|
sensor_xml_util_get_camera_probe_config(&xmlConfig, "CameraModuleConfig")
该函数把xm信息读出来赋值给xmlConfig
|
sensor_probe(module_ctrl, sd_fd, camera_cfg.sensor_name,NULL,&xmlConfig,FALSE,FALSE);
    |
    translate_sensor_slave_info(slave_info,···)
    把xml信息赋值给slave_info变量
    |
    /* Pass slave information to kernel and probe */
     memset(&cfg, 0, sizeof(cfg));
    cfg.cfgtype = CFG_SINIT_PROBE;
    cfg.cfg.setting = slave_info;
    //通过IOCTL指令:VIDIOC_MSM_SENSOR_INIT_CFG调用到内核
    if (ioctl(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
    SINFO("[%s]CFG_SINIT_PROBE failed",sensor_name);
    ret = FALSE;
    goto ERROR;
    }
    |
    msm_sensor_driver_probe
    最终调用的内核函数

注意:
如果<MountAngle>360</MountAngle>;这个值配置成360度,那么以dtsi配置的角度为准。

源码:


关于帧率
https://www.cnblogs.com/ZHJEE/p/10351155.html

继续当一名咸鱼( ̄︶ ̄)!

Stay hungry,Stay foolish!

上一篇 下一篇

猜你喜欢

热点阅读