android psensor测试,MTK camera驱动结构

和你一起终身学习,这里是程序员 Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、概述

MTK camera主要的内容在hal层,现在有hal1/hal3,当下主流的使用的是hal3,驱动主要负责sensor电源的控制以及sensor相关寄存器的操作,MTK采用设备和驱动分离的思想,抽象出imgsensor.c来控制sensor的上下电以及sensor具体的操作,结构图如下:

a615beb501fc

程序员Android转于网络

二、sensor driver介绍

Sensor driver对上响应需求,对下控制sensor硬件行为,处理器通过I2C接口来控制sensor的大部分行为,sensor输出的数据传输到TG、ISP等模块处理后,ISP将数据保存到内存中之后,才可以dump出sensor的数据,才能看到sensor的第一帧画面。这节主要介绍sensor driver的代码。

1、sensor driver函数结构体:

(1) imgsensor_mode_struct不同模式特征的结构体

这个结构体描叙了各个模式下的pclk/linelength/framelength 等:

struct imgsensor_mode_struct {

kal_uint32 pclk;

kal_uint32 linelength;

kal_uint32 framelength;

kal_uint8 startx;

kal_uint8 starty;

kal_uint16 grabwindow_width;

kal_uint16 grabwindow_height;

/* MIPIDataLowPwr2HighSpeedSettleDelayCount by different scenario */

kal_uint8 mipi_data_lp2hs_settle_dc;

/* following for GetDefaultFramerateByScenario() */

kal_uint16 max_framerate;

kal_uint32 mipi_pixel_rate;

};

对应的描叙信息如下:pclk ≈ linelength * frame_length * framerate

static kal_uint32 set_max_framerate_by_scenario(enum MSDK_SCENARIO_ID_ENUM scenario_id, MUINT32 framerate)

{

kal_uint32 frame_length;

switch (scenario_id) {

case MSDK_SCENARIO_ID_CAMERA_PREVIEW:

frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength;//计算frame_length

spin_lock(&imgsensor_drv_lock);

imgsensor.dummy_line = (frame_length > imgsensor_info.pre.framelength) ?

(frame_length - imgsensor_info.pre.framelength) : 0;

imgsensor.frame_length = imgsensor_info.pre.framelength + imgsensor.dummy_line;

imgsensor.min_frame_length = imgsensor.frame_length;

spin_unlock(&imgsensor_drv_lock);

set_dummy(); //更新新的frame_length

break;

}

sensor的linelength是固定的,每个模式的pclk也是不可调的,所以要调整帧率framerate,只能调整frame_length。set_dummy使得当前帧率立刻变化为设置的帧率,如果pclk或者linelength与对应sensor setting的实际值不一致,设置的帧率和响应的帧率会有一个偏差,画面可能出现水波纹:

a615beb501fc

程序员Android转于网络

(2) struct imgsensor_info_struct描叙sensor info常量的结构体

struct imgsensor_info_struct {

kal_uint32 sensor_id; /*record sensor id defined in Kd_imgsensor.h*/

kal_uint32 checksum_value; /*checksum value for Camera Auto Test*/

//不同mode 的信息

struct imgsensor_mode_struct pre; /*preview scenario relative information*/

struct imgsensor_mode_struct cap; /*capture scenario relative information*/

struct imgsensor_mode_struct cap1;

struct imgsensor_mode_struct cap2;

struct imgsensor_mode_struct normal_video; /*normal video scenario relative information*/

struct imgsensor_mode_struct hs_video; /*high speed video scenario relative information*/

struct imgsensor_mode_struct slim_video; /*slim video for VT scenario relative information*/

//支持的功能

kal_uint8 ae_shut_delay_frame; /*shutter delay frame for AE cycle*/

kal_uint8 ae_sensor_gain_delay_frame; /*sensor gain delay frame for AE cycle*/

kal_uint8 ae_ispGain_delay_frame; /*isp gain delay frame for AE cycle*/

kal_uint8 ihdr_support; /*1, support; 0,not support*/

kal_uint8 ihdr_le_firstline; /*1,le first ; 0, se first*/

kal_uint8 sensor_mode_num; /*support sensor mode num*/

//丢帧处理(丢掉不稳定帧的数据)

kal_uint8 cap_delay_frame; /*enter capture delay frame num*/

kal_uint8 pre_delay_frame; /*enter preview delay frame num*/

kal_uint8 video_delay_frame; /*enter video delay frame num*/

kal_uint8 hs_video_delay_frame; /*enter high speed video delay frame num*/

kal_uint8 slim_video_delay_frame; /*enter slim video delay frame num*/

kal_uint8 margin; /*sensor framelength & shutter margin*/

kal_uint32 min_shutter; /*min shutter*/

kal_uint32 max_frame_length; /*max framelength by sensor register's limitation*/

//isp驱动电流,电流过大可能会射频干扰

kal_uint8 isp_driving_current; /*mclk driving current*/

kal_uint8 sensor_interface_type; /*sensor_interface_type*/

kal_uint8 mipi_sensor_type;

/*0,MIPI_OPHY_NCSI2; 1,MIPI_OPHY_CSI2, default is NCSI2, don't modify this para*/

/*don't modify this para*/

kal_uint8 mipi_settle_delay_mode;

/*0, high speed signal auto detect; 1, use settle delay,unit is ns, */

kal_uint8 sensor_output_dataformat; /*sensor output first pixel color*/

kal_uint8 mclk; /*mclk value, suggest 24 or 26 for 24Mhz or 26Mhz*/

kal_uint8 mipi_lane_num; /*mipi lane num*/

kal_uint8 i2c_addr_table[5];

/*record sensor support all write id addr, only supprt 4must end with 0xff*/

};

(3)struct imgsensor_struct记录sensor info变量的结构体,用于动态的保存sensor的关键信息

struct imgsensor_struct {

//记录当前是normal, or H mirror, or V flip,or both H& V

kal_uint8 mirror; /*mirrorflip information*/

//记录当前处于哪种mode(init/preview/capture/video)

kal_uint8 sensor_mode; /*record IMGSENSOR_MODE enum value*/

//记录当前的shutter值

kal_uint32 shutter; /*current shutter*/

//记录当前的sensor gain值

kal_uint16 gain; /*current gain*/

kal_uint32 pclk; /*current pclk*/

kal_uint32 frame_length; /*current framelength*/

kal_uint32 line_length; /*current linelength*/

kal_uint32 min_frame_length; /*current min framelength to max framerate*/

//记录当前的dummy pixel, dummy line的值

kal_uint16 dummy_pixel; /*current dummypixel*/

kal_uint16 dummy_line; /*current dummline*/

kal_uint16 current_fps; /*current max fps*/

kal_bool autoflicker_en; /*record autoflicker enable or disable*/

kal_bool test_pattern; /*record test pattern mode or not*/

//记录当前处于哪个scenario( preview/capture/video)

enum MSDK_SCENARIO_ID_ENUM current_scenario_id;/*current scenario id*/

kal_bool ihdr_en; /*ihdr enable or disable*/

//记录当前i2c使用的address

kal_uint8 i2c_write_id; /*record current sensor's i2c write id*/

};

2、驱动入口xxxx_MIPI_RAW_SensorInit

可以看到SensorInit以函数指针的形式传入到kdSensorList结构体中:

文件位置:

kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c

struct IMGSENSOR_INIT_FUNC_LIST kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {

#if defined(XXXXX_MIPI_RAW)

{XXXXX_SENSOR_ID,

SENSOR_DRVNAME_XXXXX_MIPI_RAW,

XXXXX_MIPI_RAW_SensorInit},

#endif

......

}

UINT32 XXXXX_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc)

{

/* Check Sensor status here */

if (pfFunc != NULL)

*pfFunc = &sensor_func;

return ERROR_NONE;

}

SENSOR_FUNCTION_STRUCT这个结构体包含了所有sensor driver的操作接口:

struct SENSOR_FUNCTION_STRUCT {

MUINT32 (*SensorOpen)(void);

MUINT32 (*SensorGetInfo)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,

MSDK_SENSOR_INFO_STRUCT *pSensorInfo,

MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);

MUINT32 (*SensorGetResolution)(

MSDK_SENSOR_RESOLUTION_INFO_STRUCT * pSensorResolution);

MUINT32 (*SensorFeatureControl)(MSDK_SENSOR_FEATURE_ENUM FeatureId,

MUINT8 *pFeaturePara,

MUINT32 *pFeatureParaLen);

MUINT32 (*SensorControl)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,

MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *pImageWindow,

MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);

MUINT32 (*SensorClose)(void);

MUINT8 arch;

void *psensor_inst; /* IMGSENSOR_SENSOR_INST */

};

对应驱动中填充的信息如下:

static struct SENSOR_FUNCTION_STRUCT sensor_func = {

open,//打开camera时调用

get_info,// 获取sensor的动态信息

get_resolution,//获取sensor特定模式下的尺寸

feature_control,

control,

close

};

3、open 函数介绍及其所完成的任务

(1)此函每次打开camera都会调用;

(2)读取sensor id,确保I2C通讯正常;

(3)调用sensor_init初始化sensor芯片;

(4)初始化imgsensor结构体中的变量;

(5)读取otp中信息;

static kal_uint32 open(void)

{

//获取sensor的ID确认i2c是否正常

sensor_id = return_sensor_id();

//设置I2C 的速率

kdSetI2CSpeed(400);

//sensor初始化参数设置

sensor_init();

//初始化imgsensor结构体

imgsensor.autoflicker_en = KAL_FALSE;

imgsensor.sensor_mode = IMGSENSOR_MODE_INIT;

imgsensor.pclk = imgsensor_info.pre.pclk;

imgsensor.frame_length = imgsensor_info.pre.framelength;

imgsensor.line_length = imgsensor_info.pre.linelength;

imgsensor.min_frame_length = imgsensor_info.pre.framelength;

imgsensor.dummy_pixel = 0;

imgsensor.dummy_line = 0;

imgsensor.ihdr_en = 0;

imgsensor.test_pattern = KAL_FALSE;

imgsensor.current_fps = imgsensor_info.pre.max_framerate;

}

4、feature_control接口

(1)获取linelength和pclk:

case SENSOR_FEATURE_GET_PERIOD:

*feature_return_para_16++ = imgsensor.line_length;

*feature_return_para_16 = imgsensor.frame_length;

*feature_para_len = 4;

break;

case SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ:

*feature_return_para_32 = imgsensor.pclk;

*feature_para_len = 4;

break;

获取各个mode的sensor pclk(pixel/s),PCLK指pixel采样的时钟,

linelength, 结合pclk来计算linetime, 用来换算ae plinetable的exposure time对应的shutter (unit: line,条数)。

(2)set_shutter设置曝光行:

case SENSOR_FEATURE_SET_ESHUTTER:

set_shutter(*feature_data);

break;

设置曝光行,曝光行物理上小于frame_length,所以曝光行大于当前frame_length时,frame_length会自动撑长,

帧率降低,所以亮度较低时,帧率会下降,因为这时候shutter比较大。每个AE周期会根据AE算法找到的对应pline table中相应index的exp转换为shutter下给driver。

(3)streaming_control控制sensor输出数据:

case SENSOR_FEATURE_SET_STREAMING_SUSPEND:

pr_info("SENSOR_FEATURE_SET_STREAMING_SUSPEND\n");

streaming_control(KAL_FALSE);

break;

case SENSOR_FEATURE_SET_STREAMING_RESUME:

pr_info("SENSOR_FEATURE_SET_STREAMING_RESUME, shutter:%llu\n",

*feature_data);

if (*feature_data != 0)

set_shutter(*feature_data);

streaming_control(KAL_TRUE);

break;

在打开sensor输出数据前,需要先设置shutter。

5、control模式切换函数:

static kal_uint32 control(enum MSDK_SCENARIO_ID_ENUM scenario_id, MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,

MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)

{

spin_lock(&imgsensor_drv_lock);

imgsensor.current_scenario_id = scenario_id;

spin_unlock(&imgsensor_drv_lock);

switch (scenario_id) {

case MSDK_SCENARIO_ID_CAMERA_PREVIEW:

preview(image_window, sensor_config_data);

break;

case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:

capture(image_window, sensor_config_data);

break;

case MSDK_SCENARIO_ID_VIDEO_PREVIEW:

normal_video(image_window, sensor_config_data);

break;

case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO:

hs_video(image_window, sensor_config_data);

break;

case MSDK_SCENARIO_ID_SLIM_VIDEO:

slim_video(image_window, sensor_config_data);

break;

}

return ERROR_NONE;

}

以preview为例说明流程:

static kal_uint32 preview(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,

MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)

{

//更新imgsensor结构体信息

spin_lock(&imgsensor_drv_lock);

imgsensor.sensor_mode = IMGSENSOR_MODE_PREVIEW;

imgsensor.pclk = imgsensor_info.pre.pclk;

/* imgsensor.video_mode = KAL_FALSE; */

imgsensor.line_length = imgsensor_info.pre.linelength;

imgsensor.frame_length = imgsensor_info.pre.framelength;

imgsensor.min_frame_length = imgsensor_info.pre.framelength;

imgsensor.autoflicker_en = KAL_TRUE;

spin_unlock(&imgsensor_drv_lock);

//更新寄存器

preview_setting();

return ERROR_NONE;

}

至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值