Camera Sensor驱动修改经验

Camera Sensor驱动修改经验

点亮摄像头必须移植配置好Camera的驱动(Sensor/AF/OTP),其中Camera Sensor驱动是其中重点。Camera模组是否上电成功?I2C通信是否正常?能否读取到硬件ID?硬件ID是否匹配?寄存器设置是否正确?Fps计算是否正确?等等问题都会影响Camera是否正常工作。

记录下修改Camera Sensor Driver代码的经验,由于各平台架构不同,尽量忽略平台差异,只谈流程/参数的含义和经验。


Sensor Driver的工作

Sensor驱动代码一般不用自己写,Camera Sensor厂商会提供你需要的平台或已在别的类似平台上已经实现好的Sensor驱动代码和文档,你必须按文档里的DataSheet配置参数才能使Camera正常工作。

当你在平台上配置好(前后置)Camera Sensor的类型时,平台的代码会自动匹配到对应的驱动上。

BB端和Camera的通信一般都是I2C通信(读写Camera的寄存器)。

当Camera物理连接正常时,会先走power on上电流程,上电成功后会读取硬件id(通过I2C读取寄存器固定某个位置的值,下面会提到),匹配成功后进行初始化,写入代码里的寄存器初始化表,初始化fps计算帧率,这一步后Camera就能正常出图,随后就可以使用接口对Camera进行操作(还是I2C读写寄存器的方式),使用结束后对Camera进行下电。

上下电时序

查看硬件文档的上电时序是怎么样的,然后按照文档里的编写上电函数。上电主要对三路电压(camera包含的三路电压为模拟电压(VCAMA),数字电压(VCAMD),IO口电压(VCAMIO))、Reset脚、PDN脚、Mlck脚进行控制。

上电举个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
if (power_on) 
{
//.reset_pulse_level = SENSOR_LOW_PULSE_RESET,
//.power_down_level = SENSOR_LOW_LEVEL_PWDN,
//PDN脚拉低
hw_sensor_power_down(sns_drv_cxt->hw_handle, power_down);
//Reset脚拉低
hw_sensor_set_reset_level(sns_drv_cxt->hw_handle, reset_level);
//disable MCLK
hw_sensor_set_mclk(sns_drv_cxt->hw_handle, SENSOR_DISABLE_MCLK);
//关闭三路电压
hw_sensor_set_avdd_val(sns_drv_cxt->hw_handle, SENSOR_AVDD_CLOSED);
hw_sensor_set_dvdd_val(sns_drv_cxt->hw_handle, SENSOR_AVDD_CLOSED);
hw_sensor_set_iovdd_val(sns_drv_cxt->hw_handle, SENSOR_AVDD_CLOSED);

usleep(1 * 1000);
//设置三路电压
//.avdd_val = SENSOR_AVDD_2800MV,
// .iovdd_val = SENSOR_AVDD_1800MV,
// .dvdd_val = SENSOR_AVDD_1500MV,

hw_sensor_set_iovdd_val(sns_drv_cxt->hw_handle, iovdd_val);
usleep(1 * 1000);
hw_sensor_set_dvdd_val(sns_drv_cxt->hw_handle, dvdd_val);
usleep(1 * 1000);
hw_sensor_set_avdd_val(sns_drv_cxt->hw_handle, avdd_val);
usleep(1 * 1000);
//设置MCLK
hw_sensor_set_mclk(sns_drv_cxt->hw_handle, EX_MCLK);
usleep(10 * 1000);
//拉高PDN脚
hw_sensor_power_down(sns_drv_cxt->hw_handle, !power_down);
//拉高reset脚
hw_sensor_set_reset_level(sns_drv_cxt->hw_handle, !reset_level);
}

如果Sensor代码里没有配置下电时序,那么下电时序就是把上电时序倒过来执行一遍。


当Read ID失败的时候怎么排查

1.检查硬件连接

除了看线的连接外,要看金手指接触有没有不良的情况。

2.检查上电是否成功

看log,上电函数是否执行完成了,用万用表量对应的pin脚(三路电压/reset/pdn)状态,是否跟上电函数里设置的一样。

3.检查I2C通路是否正常

用示波器连接I2C的SDA和SCL脚,查看波形是否正常

4.检查I2C从设备地址

5.检查I2C的读写函数


Read ID正常,初始化失败了怎么办

查看log,看看fps的计算结果是否正常,检查是不是fps帧率计算有问题,一般 fps = 1000000000.0 / (frame length * line_time);要注意1000000000.0 和 line_time 的单位,可能是微秒或纳秒。一般fps的范围都在15-60之间。


参数解析

Sensor Driver代码里有很多参数,下面解析一下参数的含义和用法。

p.s.参数的值要以硬件datasheet为准。

1.I2C_SLAVE_ADDR

I2C从设备地址,硬件文档datasheet有写明,有两个地址,分别为读地址和写地址,有8位,比如

1
#define I2C_SLAVE_ADDR        0x6c   /* 8bit slave address*/

一般会右移一位,最后一位添加0为读地址,1为写地址

1
2
3
4
sensor_module_info s_c2590_module_info_tab[VENDOR_NUM] = {
...
.major_i2c_addr = I2C_SLAVE_ADDR >> 1,
...

2.硬件ID的值和在寄存器里高低位位置

1
2
3
4
#define XXXX_PID_ADDR        0x0000
#define XXXX_PID_VALUE 0x02
#define XXXX_VER_ADDR 0x0001
#define XXXX_VER_VALUE 0x02

驱动初始化里需要先检查硬件ID,就是通过读取寄存器上面两个ADDR的值,比较两个VALUE是否一致,id一致则代表连接的硬件是我们驱动对应的硬件。

3.图像尺寸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* effective sensor output image size */
#define PREVIEW_WIDTH 1600
#define PREVIEW_HEIGHT 1200
#define SNAPSHOT_WIDTH 1600
#define SNAPSHOT_HEIGHT 1200

/*Raw Trim parameters*/
#define PREVIEW_TRIM_X 0
#define PREVIEW_TRIM_Y 0
#define PREVIEW_TRIM_W 1600
#define PREVIEW_TRIM_H 1200
#define SNAPSHOT_TRIM_X 0
#define SNAPSHOT_TRIM_Y 0
#define SNAPSHOT_TRIM_W 1600
#define SNAPSHOT_TRIM_H 1200

4.line time和frame length

1
2
3
4
5
6
7
/*line time unit: 1ns*/
#define PREVIEW_LINE_TIME 54457
#define SNAPSHOT_LINE_TIME 54457

/* frame length*/
#define PREVIEW_FRAME_LENGTH 1224
#define SNAPSHOT_FRAME_LENGTH 1224

line time跟电子快门的曝光有关,是一行的曝光时间,frame length代表有多少行,一般大于图像的HEIGHT。

5.EX_MCLK

提供给Sensor的外部clock,一般不变。

1
2
/* please don't change it */
#define EX_MCLK 24

6.LANE_NUM

mipi data是成对的差分信号,MIPI_RDN和MIPI_RDP,有几对这样的pin脚,则说明是几条lane,同一颗sensor由于register setting不同,输出的信号有可能是2 lane或者4lane等

1
2
3
/*Mipi output*/
#define LANE_NUM 1
#define RAW_BITS 10

举例:MT6735,5M摄像头,有效像素为2592*1944,30fps帧率,10位ADC色彩深度,最少几lane

(1) 从平台资料可知,MIPI CSI速率最高为1.5Gbps

(2) 2592 * 1944 * 10 * 30 * (1+20%) = 1.8Gbps

lane = 1.8 / 1.5 > 1,所以最少需要 2 lane

6.MIPI_PER_LANE_BPS

一个MIPI接口每秒传输速率,单位比特每秒

1
2
#define PREVIEW_MIPI_PER_LANE_BPS     534  /* 2*Mipi clk */
#define SNAPSHOT_MIPI_PER_LANE_BPS 534 /* 2*Mipi clk */

还有其他参数,比如镜像旋转,即上下镜像左右镜像,通过设置寄存器就可以做到。但是如果相差90度,那就是模组或放置方向差了90度,要修改硬件。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×