一:基础知识
1,Image Sensor类型
a) YUV Sensor
YUV Sensor输出的Data格式为YUV,图像的效果处理使用Sensor内部的ISP,
BB端接收YUV格式的data后只进行格式的转换,效果方面不进行处理,由于Sensor内部的ISP处理能力有限,
且YUV Sensor的数据量比较大(YUV422的格式1个pixel2个byte),一般Size都比较小,常见的YUV sensor都是5M以下
b) Raw Sensor
Raw Sensor输出的Data格式为Raw,图像的效果处理使用BB端的ISP,BB端接收Raw data后进行一系列的图像处理(OB,Shading,AWB,Gamma,EE,ANR等),
效果方面由BB端控制,需要针对不同的模组进行效果调试,Raw sensor是目前的主流,
数据量比YUV Sensor小(RAW10 格式的sensor 1个pixel 10个bit)使用平台ISP处理,能支持较大的size
2,硬件接口
Camera的接口分为并行和串行两种方式,MTK平台主要支持的串行方式为mipi接口,Parallel(DVP)接口
camera包含的三路电压为模拟电压(VCAMA),数字电压(VCAMD),IO口电压(DOVDD)
MIPI CSI-2接口
CMMCLK camera工作时钟 BB提供camera的工作时钟。 ISP_MCLK1_EN(1);
RDN0/1/2/3 最大支持4-lane 一般2-lane可以搞定 mipi data是成对的差分信号,RDN和RDP,有几对这样的pin脚,则说明是几条lane
RDP0/1/2/3 同一颗sensor由于register setting不同,输出的信号有可能是2 lane或者4lane等
RCN,RCP MIP 时钟
VCAM_AF 光圈电压 一般2.8
DVDD 数字电压 有1.2 1.5 1.8 等
DOVDD GPIO口数字电压 一般1.8V
ACDD 模拟电压 2.8V或3.3V的
SDA SCL BB与Sensor端通过I2C来通信(读写寄存器)
CMPDN RESET camera 工作时序 使能管脚 复位管脚
补充说明:MIPI的camera接口叫 CSI,MIPI的display接口叫DSI。
DVP 并口
Data有10根pin,分别叫做Data0~Data9,输出的data信号是8根pin时,这八根pin接到的是Data0~Data7还是Data2~Data9
CMDAT0/1/2/3/4/5/6/7 camera的数据管脚。此数据脚可以输出的格式有YUV、RGB、JPEG等。
PCLK 为像素同步信号管脚。一个PCLK信号结束表示一个像素点的数据已经输出完毕。
XCLK 是camera的工作时钟管脚,此管脚为BB提供camera的工作时钟。
VSYNC 为camera的帧同步信号管脚。一个VYSNC信号结束表示一帧(即一个画面)的数据已经输出完毕。
HSYNC 为camera行同步信号管脚。一个HSYNC信号结束表示一行的数据已经输出完毕。
VCAM_AF 光圈电压 一般2.8
DVDD 数字电压 有1.2 1.5 1.8 等
DOVDD GPIO口数字电压 一般1.8V
ACDD 模拟电压 2.8V或3.3V的
SDA SCL BB与Sensor端通过I2C来通信(读写寄存器)
CMPDN RESET camera 工作时序 使能管脚 复位管脚
3, Camera软件架构
Camera根据Android 架构从上至下可分为
1)Applications: 最上层的应用,编译后生成Camera APK;
2)Application Framework: 主要为Applications提供API;
3)JNI: 使Application Framework和Libraries可交互;
4)Libraries: 包括Camera Framework和Camera Service(camera service和camera client);
5)HAL: 硬件抽象层, 用来链接driver和 Camera Service;
6)Kernel: image sensor driver的实作.
其中2)~4)的部分基本为Android原生的架构和code,Mediatek会有一些拓展,
而HAL和Kernel层为Mediatek主要实作的部分,Camera APK是Mediatek基于Android 原生Camera APK修改的应用.
二:点亮新camera
1. 增加ID Kernel 在kernel-3.18/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h
#define SP2609MIPI_SENSOR_ID 0x2608
#define SP2609SUBMIPI_SENSOR_ID (0x2608+1)
#define SENSOR_DRVNAME_SP2609_MIPI_RAW "sp2609mipiraw"
#define SENSOR_DRVNAME_SP2609SUB_MIPI_RAW "sp2609submipiraw"
2. 增加ID hal层 在device/mediatek/common/kernel-headers/kd_imgsensor.h
#define SP2609MIPI_SENSOR_ID 0x2608
#define SP2609SUBMIPI_SENSOR_ID (0x2608+1)
#define SENSOR_DRVNAME_SP2609_MIPI_RAW "sp2609mipiraw"
#define SENSOR_DRVNAME_SP2609SUB_MIPI_RAW "sp2609submipiraw"
3. 增加hal配置 层修改device/teksun/hys6737m_35_m0/ProjectConfig.mk ,此添加前(sp2609sub_mipi_raw)后(sp2609_mipi_raw)摄
CUSTOM_HAL_IMGSENSOR = sp2609_mipi_raw sp2609sub_mipi_raw
CUSTOM_HAL_SUB_IMGSENSOR = sp2609sub_mipi_raw
CUSTOM_HAL_MAIN_IMGSENSOR = sp2609_mipi_raw
CUSTOM_KERNEL_IMGSENSOR = sp2609_mipi_raw sp2609sub_mipi_raw
CUSTOM_KERNEL_SUB_IMGSENSOR = sp2609sub_mipi_raw
CUSTOM_KERNEL_MAIN_IMGSENSOR =sp2609_mipi_raw
4. 增加kernel配置 修改kernel-3.18/arch/arm/configs/hys6737m_35_m0_debug_defconfig,hys6737m_35_m0_defconfig
CONFIG_CUSTOM_KERNEL_IMGSENSOR="sp2609_mipi_raw sp2609sub_mipi_raw imx219_mipi_raw"
5. 添加驱动代码,放到/kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6735m/
添加FAE给的sp2609_mipi_raw文件夹 sp2609sub_mipi_raw 文件夹
6. 修改 kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6735m/camera_hw/kd_camera_hw.c
6.1 上电时序 根据fae datasheet 修改
//POWER ON
IOVDD = 1.8V
AVDD = 2.8V
DVDD = 1.5V
AFVDD = 2.8V (无)
CAMPDN=0;
CAMRST=1;
6.2 掉电时序(三个相同)
//POWER OFF
MT6735/37等4G平台只能支持到1.5V DVDD
MT6580/70/72等可以支持到1.8V DVDD
7. 修改kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6735m/kd_sensorlist.h
UINT32 SP2609_MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
UINT32 SP2609SUB_MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
#if defined(SP2609_MIPI_RAW)
{SP2609MIPI_SENSOR_ID, SENSOR_DRVNAME_SP2609_MIPI_RAW, SP2609_MIPI_RAW_SensorInit},
#endif
#if defined(SP2609SUB_MIPI_RAW)
{SP2609SUBMIPI_SENSOR_ID, SENSOR_DRVNAME_SP2609SUB_MIPI_RAW, SP2609SUB_MIPI_RAW_SensorInit},
#endif
====================================以下是HAL层====================================
8. 添加HAL层代码vendor/mediatek/proprietary/custom/mt6735/hal/D2/imgsensor/
添加FAE给的sp2609_mipi_raw文件夹 sp2609sub_mipi_raw 文件夹
9. 修改vendor/mediatek/proprietary/custom/mt6735/hal/D2/imgsensor_src/sensorlist.cpp
注意:此处camera IC的顺序应该跟kd_sensorlist.h中的顺序一致
#if defined(SP2609_MIPI_RAW)
RAW_INFO(SP2609MIPI_SENSOR_ID, SENSOR_DRVNAME_SP2609_MIPI_RAW,NULL),
#endif
#if defined(SP2609SUB_MIPI_RAW)
RAW_INFO(SP2609SUBMIPI_SENSOR_ID, SENSOR_DRVNAME_SP2609SUB_MIPI_RAW,NULL),
#endif
10. 添加cameraHAL层插值文件vendor/mediatek/proprietary/custom/mt6735/hal/D2/sendepfeature
添加文件夹sp2609_mipi_raw sp2609sub_mipi_raw,里面添加文件config.ftbl.sp2609_mipi_raw.h config.ftbl.sp2609sub_mipi_raw.h
注意:第十步,可不要,有默认配置可用 ,同IC的前后摄需要修改 Hal层做兼容
修改vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6735/hal/sensor/imgsensor_drv.cpp 中的
ImgSensorDrv::impSearchSensor(pfExIdChk pExIdChkCbf) 函数
三:调试方法
3.1. 查看硬件原理图连接--MCLK
前后摄连接在同一个MCLK上
kernel-3.18/drivers/misc/mediatek/cameraisp/src/mt6735/camera_isp_D2.c
kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6735m/camera_hw/kd_camera_hw.c
ISP_MCLK1_EN(TRUE); 是打开MCLK
ISP_MCLK1_EN(FALSE); 是关闭MCLK
3.2. 查看硬件原理图连接--i2c_num
./kernel-3.18/drivers/misc/mediatek/imgsensor/src/mt6735m/kd_sensorlist.c
#ifndef SUPPORT_I2C_BUS_NUM1
#define SUPPORT_I2C_BUS_NUM1 0 //I2C0 主摄像头
#endif
#ifndef SUPPORT_I2C_BUS_NUM2
#define SUPPORT_I2C_BUS_NUM2 2 //I2C1 双前摄
#endif
以及查看I2C速率 大小 一般是100K-400K之间
g_pstI2Cclient->timing = 400; /* 100k */
3.3. 查看硬件原理图连接--mipi/DVP
看是采用那种接口方式,配置MIPI 口或者DVP口
3.4. 上电下电
主要是电压大小,和GPIO中配置的PDN 和RESET口是否一致.
3.5. 摄像头上下左右颠倒
1. 格科的GC系列: 驱动中都有相关的宏可以控制 - 开关就行(四选一)
#define IMAGE_NO_MIRROR
//#define IMAGE_H_MIRROR
//#define IMAGE_V_MIRROR
//#define IMAGE_HV_MIRROR
2. 思比科的sp系列 与 ov公司的ov系列 与 sony 的imx系列 :
直接修改寄存器
hal层还有一个地方可以改,作用与所有摄像头
vendor/mediatek/proprietary/custom/mt6735/hal/D2/imgsensor_src/cfg_setting_imgsensor.cpp
static SensorOrientation_T const inst = {
u4Degree_0 : 90, // main sensor in degree (0, 90, 180, 270)
u4Degree_1 : 270, // sub sensor in degree (0, 90, 180, 270)
u4Degree_2 : 90, // main2 sensor in degree (0, 90, 180, 270)
};
3.6. 插值修改(即像素作假)
#if 1
// Picture Size (Both width & height must be 16-aligned)
FTABLE_CONFIG_AS_TYPE_OF_DEFAULT_VALUES(
KEY_AS_(MtkCameraParameters::KEY_PICTURE_SIZE),
SCENE_AS_DEFAULT_SCENE(
ITEM_AS_DEFAULT_("1920x1088"), /* default 200w */ // 二数相乘即是像素
ITEM_AS_VALUES_(
"320x240", "640x480", "1280x960", "1600x1200", "2048x1536", "2560x1920", /* 4:3*/ // QVGA/VGA/1MP/2MP/3MP/5MP
"320x180", "640x360", "1280x720", "1600x912", "2048x1152", "2560x1440", /* 16:9*/ // QVGA/VGA/1MP/2MP/3MP/5MP
"400x240", "640x384", "1280x768","1600x960", "2560x1536", /* 5:3*/ // QVGA/VGA/1MP/2MP/5MP
)
),
)
#endif
3.7. 摄像头变焦倍数设置:1.0/1.1倍等
#if 1
// Zoom 变焦
FTABLE_CONFIG_AS_TYPE_OF_USER(
KEY_AS_(MtkCameraParameters::KEY_ZOOM),
SCENE_AS_DEFAULT_SCENE(
ITEM_AS_DEFAULT_("0"), //Zoom Index
ITEM_AS_USER_LIST_(
//Zoom Ratio
"100", "114", "132", "151", "174", // 原本分别为1.0/1.1/1.3/.../4.0倍变焦
"200", "229", "263", "303", "348",
"400",
)
),
)
#endif
3.8. 相机菜单中删除或增加某些场景如HDR
#if 1
// Scene Mode
FTABLE_CONFIG_AS_TYPE_OF_DEFAULT_VALUES(
KEY_AS_(MtkCameraParameters::KEY_SCENE_MODE),
SCENE_AS_DEFAULT_SCENE(
ITEM_AS_DEFAULT_(MtkCameraParameters::SCENE_MODE_AUTO),
ITEM_AS_VALUES_(
MtkCameraParameters::SCENE_MODE_AUTO,
// MtkCameraParameters::SCENE_MODE_NORMAL,
MtkCameraParameters::SCENE_MODE_PORTRAIT,
MtkCameraParameters::SCENE_MODE_LANDSCAPE,
MtkCameraParameters::SCENE_MODE_NIGHT,
MtkCameraParameters::SCENE_MODE_NIGHT_PORTRAIT,
MtkCameraParameters::SCENE_MODE_THEATRE,
MtkCameraParameters::SCENE_MODE_BEACH,
MtkCameraParameters::SCENE_MODE_SNOW,
MtkCameraParameters::SCENE_MODE_SUNSET,
MtkCameraParameters::SCENE_MODE_STEADYPHOTO,
MtkCameraParameters::SCENE_MODE_FIREWORKS,
MtkCameraParameters::SCENE_MODE_SPORTS,
MtkCameraParameters::SCENE_MODE_PARTY,
MtkCameraParameters::SCENE_MODE_CANDLELIGHT,
MtkCameraParameters::SCENE_MODE_HDR,
)
),
)
#endif
3.9. 白平衡 - 增删改查
#if 1
// White Balance.
FTABLE_CONFIG_AS_TYPE_OF_DEFAULT_VALUES(
KEY_AS_(MtkCameraParameters::KEY_WHITE_BALANCE),
SCENE_AS_DEFAULT_SCENE(
ITEM_AS_DEFAULT_(MtkCameraParameters::WHITE_BALANCE_AUTO),
ITEM_AS_VALUES_(
MtkCameraParameters::WHITE_BALANCE_AUTO, MtkCameraParameters::WHITE_BALANCE_INCANDESCENT,
MtkCameraParameters::WHITE_BALANCE_FLUORESCENT, MtkCameraParameters::WHITE_BALANCE_WARM_FLUORESCENT,
MtkCameraParameters::WHITE_BALANCE_DAYLIGHT, MtkCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
MtkCameraParameters::WHITE_BALANCE_TWILIGHT, MtkCameraParameters::WHITE_BALANCE_SHADE,
)
),
//......................................................................
#if 1 // SCENE LANDSCAPE
SCENE_AS_(MtkCameraParameters::SCENE_MODE_LANDSCAPE,
ITEM_AS_DEFAULT_(MtkCameraParameters::WHITE_BALANCE_DAYLIGHT),
ITEM_AS_VALUES_(
MtkCameraParameters::WHITE_BALANCE_AUTO, MtkCameraParameters::WHITE_BALANCE_INCANDESCENT,
MtkCameraParameters::WHITE_BALANCE_FLUORESCENT, MtkCameraParameters::WHITE_BALANCE_WARM_FLUORESCENT,
MtkCameraParameters::WHITE_BALANCE_DAYLIGHT, MtkCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
MtkCameraParameters::WHITE_BALANCE_TWILIGHT, MtkCameraParameters::WHITE_BALANCE_SHADE,
)
)
#endif
//......................................................................
#if 1 // SCENE SUNSET
SCENE_AS_(MtkCameraParameters::SCENE_MODE_SUNSET,
ITEM_AS_DEFAULT_(MtkCameraParameters::WHITE_BALANCE_DAYLIGHT),
ITEM_AS_VALUES_(
MtkCameraParameters::WHITE_BALANCE_AUTO, MtkCameraParameters::WHITE_BALANCE_INCANDESCENT,
MtkCameraParameters::WHITE_BALANCE_FLUORESCENT, MtkCameraParameters::WHITE_BALANCE_WARM_FLUORESCENT,
MtkCameraParameters::WHITE_BALANCE_DAYLIGHT, MtkCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
MtkCameraParameters::WHITE_BALANCE_TWILIGHT, MtkCameraParameters::WHITE_BALANCE_SHADE,
)
)
#endif
//......................................................................
#if 1 // SCENE CANDLELIGHT
SCENE_AS_(MtkCameraParameters::SCENE_MODE_CANDLELIGHT,
ITEM_AS_DEFAULT_(MtkCameraParameters::WHITE_BALANCE_INCANDESCENT),
ITEM_AS_VALUES_(
MtkCameraParameters::WHITE_BALANCE_AUTO, MtkCameraParameters::WHITE_BALANCE_INCANDESCENT,
MtkCameraParameters::WHITE_BALANCE_FLUORESCENT, MtkCameraParameters::WHITE_BALANCE_WARM_FLUORESCENT,
MtkCameraParameters::WHITE_BALANCE_DAYLIGHT, MtkCameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
MtkCameraParameters::WHITE_BALANCE_TWILIGHT, MtkCameraParameters::WHITE_BALANCE_SHADE,
)
)
#endif
//......................................................................
)
#endif
3.10. 单独编译camera hal层:
source ./build/envsetup.sh && full_hys6737m_35_m0-eng
mmma vendor/mediatek/proprietary/custom/mt6735/hal
编译生成
./out/target/product/hys6737m_35_m0/obj/lib/libcameracustom.so
push到手机
adb remount
adb push *** /system/lib/
adb shell
rm -r /data/media/0/mtklog
reboot
插值 编译
./vendor/mediatek/proprietary/hardware/mtkcam/legacy/v1/common/paramsmgr/feature/custom/Android.mk:117
MY_CUST_FTABLE_PATH += $(MTK_PATH_CUSTOM_PLATFORM)/hal/D2/sendepfeature
mmm ./vendor/mediatek/proprietary/hardware/mtkcam/legacy/ //修改参数摄像头参数 可以单编
编译生成 需要
out/target/product/hys6737m_35_m0/system/lib/libcam.paramsmgr.so
push到手机
查看是否读到ID
cat /proc/driver/camera_info
直接在驱动那打印log
四:调试案例
案例一 : 后摄gc2235读不到ID - 引脚配置不对 ,I2C总线不对。
现象 : 单点前摄ov8865不亮
平台 : androidN,MTK6737
排查过程: 1. adb查看是否读到id(cat /dev/driver/camera_info),显示未读到id
2. 查看mtklog(kernel_log.boot),发现因为i2c通讯出错导致读id失败
3. 查看原理图。PWD RESET 引脚配置不对 ,I2C总线不对。硬件已经修改,不能用MTK默认的
修改后-> 成功读到id
处理方案: 修改PWD RESET ,I2C总线
总结 : 1.camera读不到id可能的原因: 引脚配置不对_上电时序不对_i2c地址不对_i2c速率不合适_模组打样有问题
案例二 : gc2053_mipi_raw软件编译问题
gc2053_mipi_raw/gc2053mipi_Sensor.h:30:5: error: unknown type name 'kal_uint32'
kal_uint32 需要#include kd_camera_typedef.h
gc2053mipi_Sensor.c:206:13: error: function declaration isn't a prototype [-Werror=strict-prototypes]
static void set_dummy()
^
可以修改编译规则 也可以需要修改成static void set_dummy(void)