文章目录
- 1.动态调试camera寄存器
- 2.log打开
- 3.sensor信息
- 4.isp出帧
- 5.android.hardware.camera.raw.xml
- 6.media_profiles.xml
- 7.mipi lane问题
- 8.test_ev_compensation_advanced
- 9.CCU
- 10.flicker
- 11.cts 帧率测试相关
- 12.耗时
- 13. SENSOR_INFO_SENSITIVITY
- 14.size配置
- 15.adb 查看引脚状态
- 16.驱动size配置
- 17.平台sensor代码参考
- 18.i2c bus相关配置
- 19.添加二供编译报错
- 20.开机不search main3
- 21.平台支持最大camera个数
- 22.工程模式
- 23. 抓串口log
- 24. gpio dump
- 25. gpio配置一直为高
- 26.读id 冲突
- 27.待机af漏电
- 28.动态调试Scenario
- 29.gsi屏蔽camera
- 30.isp_driving_current mclk的驱动电流相关及配置
- 31.平台端otp size问题
- 32.isp版本
- 33.mtk mfnr
- 34.mtk tag与android tag转换
- 35.camera id引脚二供兼容
- 36.cts测试中log打印
- 37.PMIC调试
- 37.af漏电一直为高
- 38.mipi 速率
- 39.流程log关键字
- 40.vbanking 计算
- 41.sensor gain配置
- 42.af相关配置以及metadata
- 43.rrzo mdp
- 44.调用栈打印
- 45 dump 符号表
- 46 cts FOV测试
- 47 双摄硬同步
- 48 Camera lane 数的理论计算
1.动态调试camera寄存器
FAQ05758
首先确保驱动中
sensor driver(XXX_sensor.c)中正确实现相应的feature control:
UINT32 XXX_FeatureControl(MSDK_SENSOR_FEATURE_ENUM FeatureId,
UINT8 *pFeaturePara,UINT32 *pFeatureParaLen)
{
...
case SENSOR_FEATURE_SET_REGISTER:
XXX_write_cmos_sensor(pSensorRegData->RegAddr, pSensorRegData->RegData);
break;
case SENSOR_FEATURE_GET_REGISTER:
pSensorRegData->RegData = XXX_read_cmos_sensor(pSensorRegData->RegAddr);
break;
...
}
打开camera
adb shell echo “addr” > /proc/driver/camsensor3
然后cat /proc/driver/camsensor3 查看结果
B:/proc/driver # echo "300b" > camsensor
B:/proc/driver # cat camsensor
addr = 0x0000300b, data = 0x00000088
写同理
adb shell echo “addr para” > /proc/driver/camsensor3
注意,add 与 para均是16进制
2.log打开
mtk通用log
adb root
adb shell setprop persist.mtk.camera.log_level 3
adb shell setprop persist.vendor.mtk.camera.log_level 3
adb root
adb shell setenforce 0
isp问题:
adb shell setprop debug.camera.log.p1node 2
adb shell setprop debuglog.imageio.iopipe 3
adb shell setprop debug.camera.log 1
adb shell setprop debug.camera.log.hal3a 1
adb shell setprop persist.mtk.camera.log_level 3
adb shell setprop debug.camera.log 5
adb shell setprop debug.aao_buf_mgr.enable 1
adb shell setprop debug.afo_buf_mgr.enable 1
其他
adb shell setprop persist.vendor.mtk.camera.log_level 3
adb shell setprop persist.vendor.debug.camera.log 2
adb shell setprop persist.mtk.camera.log_level 3
adb shell setprop persist.vendor.mtk.camera.log_level 3
adb shell setprop vendor.debug.mapping_mgr.enable 2
adb shell setprop debug.hal3av3.log 263
adb shell setprop debug.paramctrl.enable 1
its相关:
adb root
adb shell setenforce 0
adb shell setprop persist.vendor.mtk.camera.log_level 3
adb shell setprop vendor.debug.camera.log 3
adb shell setprop vendor.debug.camera.log.hal3a 1
adb shell setprop vendor.debug.hal3av3.log 263
adb shell setprop vendor.debug.3a.log 1
adb shell setprop debug.cam.drawid 1
adb shell setprop vendor.debug.hal3a.task 1
adb shell setprop vendor.debug.aaa_sensor_mgr.enable 1
adb shell setprop vendor.debug.ae_mgr.enable 1
adb shell setprop vendor.debug.aaa.pvlog.enable 1
adb shell setprop vendor.debug.camera.log.p1node 3
adb shell setprop vendor.flash_is_debug 1
adb shell pkill camera*
打闪相关:
----------------for ae
adb shell setprop debug.ae_mgr.enable 1
adb shell setprop debug.aaa.pvlog.enable 1
adb shell setprop debug.ae.enable 9
adb shell setprop debug.ae.plineinfo 1(for algo pline info)
---------------for hal3a
adb shell setprop debug.camera.log 1
adb shell setprop debug.hal3av3.log 263 // Hal3AAdapter3.cpp
adb shell setprop debug.camera.log.hal3a 1 // Hal3AFlowCtrl.cpp
adb shell setprop debug.3a.log 1 // Thread3AImp.cpp
adb shell setprop debug.thread_raw.log 1 // ThreadRawImp.cpp
adb shell setprop debug.aaa_state.enable 1
---------------for flashlight
adb shell setprop debug.z.flash_verbose_en 1
adb shell setprop debug.camera.log 1
3a相关:
adb root
adb shell setenforce 0
adb shell setprop persist.vendor.mtk.camera.log_level 3
adb shell setprop vendor.debug.camera.log 3
adb shell
setprop vendor.debug.camera.log.hal3a 1
adb shell setprop vendor.debug.hal3av3.log 263
adb shell setprop vendor.debug.3a.log 1
adb shell setprop vendor.debug.hal3a.task 1
adb shell setprop vendor.debug.aaa_sensor_mgr.enable 1
adb shell setprop vendor.debug.ae_mgr.enable 1
adb shell setprop vendor.debug.aaa.pvlog.enable 1
adb shell setprop vendor.debug.camera.log.p1node 2
adb shell setprop debug.cam.drawid 1adb shell pkill cameraserver
adb shell pkill camerahalserver
3.sensor信息
查看meta data 配置是否生效
adb shell dumpsys media.camera -v 2 > meta.info.txt
获取camera info (sensor name,各个size的size配置,delay frame的配置等)
adb shell cat /proc/driver/camera_info
MIPI pixel rate check
adb shell sentest [sensorDev] [scenario]
• sensorDev - 1:main, 2:sub, 4:main2, ……
• Scenario - 0:preview, 1:capture, 2: normal_video, ……***
4.isp出帧
FAQ18079
关键log(kernel):P1_SOF 或 DON 或ISP
releaseAction] [Cam:
CAMA P1_SOF
CAMB P1_SOF
main: P1NodeImp 也会打印SOF
源码路径:
/kernel-4.14/drivers/misc/mediatek/cameraisp/src/mt6765/camera_isp.c
将 #define ISP_DEBUG打开,可以看到更多log
5.android.hardware.camera.raw.xml
- 这些feature项的配置有两个地方:
a./frameworks/native/data/etc/xxxx.xml //xxxx表示不同feature name
b./device/mediatekprojects/xxxx/ //xxxx表示当前project
对应有android.app.cts.SystemFeaturesTest#testCameraFeatures
常见修改autofocus与capability.raw根据实际情况配置或者注释掉。
如:CtsAppTestCases
android.app.cts.SystemFeaturesTest#testCameraFeatures
Fail Details:java.lang.AssertionError: PackageManager#hasSystemFeature should return true for android.hardware.camera.level.full
则在相应android.hardware.camera.xml文件加上
<feature name="android.hardware.camera.level.full" />
添加"android.hardware.camera.capability.raw功能时,要注意添加对应metadata,
如:
camera 的CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW的
在 config_static_metadata_scaler.h 增加
CONFIG_ENTRY_VALUE(HAL_PIXEL_FORMAT_RAW16, MINT32)
CONFIG_ENTRY_VALUE(640, MINT32)
CONFIG_ENTRY_VALUE(960, MINT32)
CONFIG_ENTRY_VALUE(MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, MINT32)
.............
CONFIG_ENTRY_VALUE(HAL_PIXEL_FORMAT_RAW16, MINT64)
CONFIG_ENTRY_VALUE(640, MINT64)
CONFIG_ENTRY_VALUE(960, MINT64)
CONFIG_ENTRY_VALUE(33333333, MINT64)
同时在config_static_metadata_request_commonType.h添加声明:
CONFIG_METADATA_BEGIN(MTK_REQUEST_AVAILABLE_CAPABILITIES)//new
........
CONFIG_ENTRY_VALUE(MTK_REQUEST_AVAILABLE_CAPABILITIES_RAW, MUINT8) //添加
........
CONFIG_METADATA_END()
●相机硬件功能 android.hardware.camera
应用使用设备的后置相机。只有前置相机的设备不会列出该功能,因此如果您的应用可与任何朝向的相机通信,请改用android.hardware.camera.any 功能。●android.hardware.camera.any 应用使用设备的其中一个相机或用户为设备连接的外置相机。
如果您的应用不要求相机必须是后置式,请使用此值来替代 android.hardware.camera。●android.hardware.camera.autofocus 应用使用设备相机支持的自动对焦功能。 应用通过使用该功能暗示其还使用 android.hardware.camera 功能,除非这个父功能在声明时使用了 android:required=”false”。
● android.hardware.camera.capability.manual_post_processing 应用使用设备相机支持的
MANUAL_POST_PROCESSING 功能。 您的应用可以通过该功能替换相机的自动白平衡功能。 使用
android.colorCorrection.transform、android.colorCorrection.gains 以及
TRANSFORM_MATRIX 的 android.colorCorrection.mode。● android.hardware.camera.capability.manual_sensor 应用使用设备相机支持的
MANUAL_SENSOR 功能。 该功能隐含对自动曝光锁定 (android.control.aeLock)
的支持,该支持可以让相机的曝光时间和灵敏度一直固定在特定值。●android.hardware.camera.capability.raw 应用使用设备相机支持的 RAW 功能。 该功能暗示设备可以保存
DNG(原始)文件,并且设备的相机提供您的应用直接处理这些原始图像所需的 DNG 相关元数据。●android.hardware.camera.external 应用与用户为设备连接的外置相机通信。
但该功能不能保证外置相机可供您的应用使用。●android.hardware.camera.flash 应用使用设备相机支持的闪光功能。 应用通过使用该功能暗示其还使用
android.hardware.camera 功能,除非这个父功能在声明时使用了 android:required=”false”。●android.hardware.camera.front 应用使用设备的前置相机。 应用通过使用该功能暗示其还使用
android.hardware.camera 功能,除非这个父功能在声明时使用了 android:required=”false”。● android.hardware.camera.level.full 应用使用设备的至少一个相机提供的 FULL 级图像捕捉支持。 提供
FULL 支持的相机可提供快速捕捉功能、逐帧控制和手动后期处理控制。
6.media_profiles.xml
mtk 解释
media_profiles.xml编解码讲解
客制化问题
cts源码:android/cts/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
实际情况实际分析,media_profiles.xml 需要遵循几个原则,不然会导致cts一系列问题。
7.mipi lane问题
参考:https://blog.csdn.net/weixin_38328785/article/details/112131386
DPHY
vendor/mediatek/proprietary/custom/project/hal/imgsensor_src/cfg_setting_imgsensor.cpp
这里是csi 0~4, 4lane。如果要拆分的话,直接配置成如CUSTOM_CFG_CSI_PORT_0A与CUSTOM_CFG_CSI_PORT_0B 就是将csi0拆分成2lane了。
一般是定义在对应平台的
mt6779/hal/inc/camera_custom_imgsensor_cfg.h中
另外,sensor驱动中还需指定.mipi_lane_num = SENSOR_MIPI_4_LANE,//mipi lane num
FAQ22847
当配置未生效或者不知道走哪一个文件时,可以加log确认
/vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1_1/imgsensor_drv.cpp
将 //#define SENDCMD_LOG
注释打开即可
794 case CMD_SENSOR_GET_MCLK_CONNECTION:
795 *parg1 = m_pCustomCfg->mclk;
796 #ifdef SENDCMD_LOG
797 LOG_MSG("[CMD_SENSOR_GET_MCLK_CONNECTION] *parg1 = %d", (MUINT32)*parg1);
798 #endif
799 break;
800
801 case CMD_SENSOR_GET_MIPI_SENSOR_PORT:
802 *parg1 = m_pCustomCfg->port;
803 #ifdef SENDCMD_LOG
804 LOG_MSG("[CMD_SENSOR_GET_MIPI_SENSOR_PORT]");
805 #endif
806 break;
8.test_ev_compensation_advanced
FAQ21801
参考:test_ev_compensation_advanced.py_.pdf
主要是这两处
AE_COMPENSATION_RANGE一般是-4,4,也有-6,6等值。
AE_COMPENSATION_STEP一般是1,2,这里step为2,测试时就是从-6,-4,-2这样。
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_SENSITIVITY_RANGE)
CONFIG_ENTRY_VALUE(100, MINT32)
CONFIG_ENTRY_VALUE(1200, MINT32)///12xgain
CONFIG_METADATA_END()
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_EXPOSURE_TIME_RANGE)// 100 us - 400ms
CONFIG_ENTRY_VALUE(100000L, MINT64)
CONFIG_ENTRY_VALUE(200000000L, MINT64) ///最大曝光时间是200ms
CONFIG_METADATA_END()
CONFIG_METADATA_BEGIN(MTK_SENSOR_MAX_ANALOG_SENSITIVITY)
CONFIG_ENTRY_VALUE(128, MINT32) ///这里目前配置的是128,这里通常配置的是最大的sensor gain
CONFIG_METADATA_END()
SENSITIVITY_RANGE 值是否合适(该值由SENSOR_MAX_ANALOG_SENSITIVIT和平台gain倍数决定,但一般均不用最大值),如在ev较大时(如4或6时)实际值低于期望值太多,则减小此处配置最大值可能能过,但是可能导致DUO ready test失败。
通过日志查看对应的ev值的log ,检测 ae_mgr中收到的ev 是否正确,如果不正确请提case给MTK
Sensor driver中是否有正确收到对应的shutter和gain,如果没有收到,请提
case给MTK
如果有正确收到对应的shutter和gain,请找sensor vendor解决sensor 设置对
应的ae值,表现不如预期的原因。
ae_mgr 为logtag
//==========================================================================
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_MAX_FRAME_DURATION)// 30 sec
CONFIG_ENTRY_VALUE(200000000L, MINT64)
CONFIG_METADATA_END()
MAX_FRAME_DURATION为最小帧率对应的帧间隔,要求大于等于SENSOR_INFO_EXPOSURE_TIME_RANGE的值
9.CCU
ccu有单独的mcu,在CCU中跑AE相关运算,可以省掉CPU的AE运算时间。
其中,
- ccu shutter&gain:
表示通过 ccu 调用i2c接口写入 sensor 的shutter 和 gain。
可以省掉 cpu 调用i2c接口的时间,但不能加速AE收敛。 - CCU AE Algo:
在ccu中跑AE Algo。
可以省掉 cpu 跑AE Algo的时间,而且可以加速AE 收敛。 - 能否切到cpu AE Algo:
表示当前平台是否强制跑CCU AE Algo,对于强制跑CCU AE Algo 的平台,不支持传统的CPU AE Algo。
因为是编译时从驱动中拿ae相关函数,所以,在命名上,有一定要求,否则编译不过。
1.sensor名字,在kd_imgsensor.h中定义,且必须遵循SENSOR_NAME_+<sensor_name>,如SENSOR_NAME_OV8856_MIPI_RAW
2.驱动头文件命名,去掉.h后应与.c相同
3. iWriteRegI2C • iWriteRegI2CTiming • iReadRegI2C • iReadRegI2CTiming使用默认i2c读写函数
4. sensor挂载的i2c bus,需要支持2路以上,具体平台不同
log:
adb root
adb shell setprop vendor.debug.drv.ccu_drv 5
adb shell setprop vendor.debug.ccuif.ccu_drv 5
adb shell pkill camera*
tag:CcuDrv 或I2C wr dump
10.flicker
交流电照明灯发出的光会以一定频率抖动,导致sensor图像出现行方向的水波纹,称之为flicker。目前主要的交流电频率有50Hz(中国)和60Hz两种。为了避免出现flicker,要求曝光时间大于base值时必须是base的整数倍。
当出现flicker时,首先要判断曝光时间是否正确,打印曝光寄存器值,看是否是base的整数倍;如果是base的整数倍,那么就得确认所用的行长和频率是否正确;如果都正确就需要向研发反映,可能sensor功能异常或者是行干扰。
11.cts 帧率测试相关
常见为testCameraToSurfaceTextureMetadata与testPreviewFpsRange等
debug方法:
1)上层成功设定15fps到camera kernel driver部分。
见log:
[ 6985.842845] (1)[26035:3ATHREAD][name:×××mipi_Sensor&]×××_camera_sensor[set_max_framerate_by_scenario] scenario_id = 0, framerate = 150
2)在随后的log中,搜索P1_SOF,发现两帧之间时间差为33ms,即sensor的帧率是30fps。这说明虽然设定了15fps的帧率到sensor,但其仍然输出30fps。
见log:
[ 6986.034669] -(0)[26036:AFthread][name:camera_isp_D2&][ISP_D2] P1_SOF_13
[ 6986.067636] (2)[26035:3ATHREAD][name:camera_isp_D2&][ISP_D2] P1_SOF_14
两帧时间差是6986.067636-6986.034669 = 32967,约33ms
看一下testPreviewFpsRange的log,此时就可按照上面的方法排查
两个方向
上层有没有把帧率下发下来(检查flow,rang 配置等)
如有下发,实际出帧是否符合预期 (检查驱动set_dummy函数,写帧长函数,性能)
12.耗时
power on 阶段,主要耗时在上电上面
<7>[ 73.402464] (6)[4470:powerOnSensor0][imgsensor][IMGSENSOR_PROFILE] [imgsensor][kdCISModulePowerOn]Profile = 28812 us
sensor open时,会有 init操作,主要是init 写寄存器
<7>[ 73.503729] (6)[4470:powerOnSensor0][imgsensor][IMGSENSOR_PROFILE] [imgsensor][SensorOpen]Profile = 130085 us
Preview setting/Capture setting 下这些setting时也会有耗时
<7>[ 73.884306] (4)[4516:HwBinder:815_1]S5K3L6_camera_sensor[control] scenario_id = 1
<7>[ 73.884311] (4)[4516:HwBinder:815_1]S5K3L6_camera_sensor[capture] E
<7>[ 73.884317] (4)[4516:HwBinder:815_1]S5K3L6_camera_sensor[capture_setting] capture_setting() E! currefps:300
<14>[ 73.889788] (0)[339:init]init 26: [73858][200]ReapLogT PropSet [debug.tracing.screen_brightness]=[0.8]73657 Done
<7>[ 73.892507] (0)[4516:HwBinder:815_1]S5K3L6_camera_sensor[set_mirror_flip] S5K3L6_camera_sensor[set_mirror_flip] image_mirror = 0
<7>[ 73.893308] (0)[4516:HwBinder:815_1][imgsensor][IMGSENSOR_PROFILE] [imgsensor][SensorControl]Profile = 8989 us
13. SENSOR_INFO_SENSITIVITY
metadata中
MTK_SENSOR_MAX_ANALOG_SENSITIVITY => Sensor analog gain only
这里是sensor支持的最大again。
当android.sensor.sensitivity值小于或等于这个值时,所有的应用增益必须是模拟的again。对于大于这个的数值,增益可以是模拟和数字的混合。
MTK_SENSOR_INFO_SENSITIVITY_RANGE => Sensor gain + isp gain
一般来说,MTK_SENSOR_INFO_SENSITIVITY_RANGE (100,16000)
isp gain就是10倍。
平台最新基线,在
vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/constructStaticMetadata.cpp
中,限制重写了MTK_SENSOR_INFO_SENSITIVITY_RANGE的最大值,会直接在MTK_SENSOR_MAX_ANALOG_SENSITIVITY 的基础上放大10倍,metadata中配置无效。
对于更新的平台,最大会到19200,具体看constructStaticMetadata.cpp实现
14.size配置
HAL_PIXEL_FORMAT_BLOB 代表jepg 格式
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 代表yuv 格式
HAL_PIXEL_FORMAT_YCbCr_420_88 代表yuv 格式
三个格式的分析率不相关,按需配置
目前在P版本上:
三个格式的分辨率,必须满足如下规则<= android.sensor.info.activeArraySize <=android.sensor.info.pixelArraySize 且长宽必须被16整除的条件下,可以随便设置。
在O版本上:
可以做插值不必满足<= android.sensor.info.activeArraySize<=android.sensor.info.pixelArraySize
下面三个metadata有什么区别?
metadata对应的key
MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS android.scaler.availableStreamConfigurations
MTK_SCALER_AVAILABLE_MIN_FRAME_DURATIONS android.scaler.availableMinFrameDurations
MTK_SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations
针对每个size,都需要在
MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS ,MTK_SCALER_AVAILABLE_MIN_FRAME_DURATIONS ,MTK_SCALER_AVAILABLE_STALL_DURATIONS
这三个里面配置
HAL_PIXEL_FORMAT_BLOB
HAL_PIXEL_FORMAT_YCbCr_420_888两组
config_static_metadata_scaler.h中配置如下三个tag就可以了
MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
MTK_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
MTK_SCALER_AVAILABLE_STALL_DURATIONS
注意点:
1.每个tag中对应的size必须都有,就是在第一个tag中填了一个size,在后面两个tag中也必须有这个size
2.每个size对应有三种类型BLOB、RAW16、YUV,RAW16只需要填一组就可以了(此size为sensor可以输出的最大size)
3.tag中有MTK_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT的项不要去改动,只需要改output的就可以了
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED是预览尺寸
log
1.在AP log中可以搜索关键字:getTargetPreviewSize
2. 在hal层中log中搜关键字:evaluatePreviewSize ------> evaluate preview size
帧持续时间配置:
每个分辨率的最后一项(如:66666666)都需进行计算
数值计算方法:每帧最大持续时间只能是以下3个值中的一个(ns)
1000000000/15=66666666
1000000000/20=50000000
1000000000/30=33333333
每帧最大持续时间=H * W / 200*1000(选取大于且与其最接近的上述3个值中的一个)
如:
CONFIG_ENTRY_VALUE(HAL_PIXEL_FORMAT_BLOB, MINT64)
CONFIG_ENTRY_VALUE(3968, MINT64)
CONFIG_ENTRY_VALUE(2976, MINT64)
CONFIG_ENTRY_VALUE(66666666, MINT64)
3968 * 2976 / 200 * 1000=59043000,
与66比较接近,则配置为66666666
关于帧持续时间与帧停顿时间:
可参考:
SENSOR_FRAME_DURATION:
从当前帧曝光开始到下一帧曝光开始的持续时间,
getOutputMinFrameDuration:
getOutputStallDuration
以下格式可能总是有一个停顿持续时间:JPEG RAW16 RAW_PRIVATE
以下格式永远不会有停顿时间:YUV_420_888 PRIVATE
15.adb 查看引脚状态
cd /sys/devices/platform
ls | grep pinctrl
如:pinctrl@1000b000
进入pinctrl@1000b000目录:
查看gpio100状态
cat mt_gpio | grep 100:
at mt_gpio | grep 100: <
100: 0100020110
at mt_gpio | grep 100: <
100: 1101020110
供电的LDO ,GPIO
会是这两种状态:
at mt_gpio | grep 167: <
167: 0100000110
at mt_gpio | grep 167: <
167: 0111000110
PIN (MODE)(DIR)(DOUT)(DIN)(DRIVE)(SMT)(IES)(PULL_EN)(PULL_SEL)(R1 R0)
000 0001001111
GPIO0: mode-0(具体mode对应GPIO实际设计需求), DIR-0也就是GPIO设置为输入(1为输出),Dout-0,DIN-1即输入电平为1,DRIVE-00, SMT-1,IES-1(设置输入时IES必须设置为1), PULL_EN-1(只有设置为1后才能使能上下拉), PULL_SEL-1(上拉)—设置OK
001 0000001110
GPIO1: mode-0(具体mode对应GPIO实际设计需求), DIR-0也就是GPIO设置为输入(1为输出),Dout-0,DIN-0即输入电平为0,DRIVE-00, SMT-1,IES-1(设置输入时IES必须设置为1), PULL_EN-1(只有设置为1后才能使能上下拉), PULL_SEL-0(下拉)—设置ok
002 0000001111
GPIO1: mode-0(具体mode对应GPIO实际设计需求), DIR-0也就是GPIO设置为输入(1为输出),Dout-0,DIN-0即输入电平为0,DRIVE-00, SMT-1,IES-1(设置输入时IES必须设置为1), PULL_EN-1(只有设置为1后才能使能上下拉), PULL_SEL-1(使能上拉)—上拉电阻到输入口可以产生漏电,但是由于上拉电阻为75K(default),电流较小可以忽略
adb命令拉高拉低
adb shell “chmod 777 /sys/devices/platform/pinctrl/mt_gpio”
adb shell “cat /sys/devices/platform/pinctrl/mt_gpio | grep 134”
adb shell “echo out 134 0 > /sys/devices/platform/pinctrl/mt_gpio”
adb shell “echo out 134 1 > /sys/devices/platform/pinctrl/mt_gpio”
6765平台就是
adb shell “echo out 6 0 > /sys/devices/platform/pinctrl@1000b000/mt_gpio”
16.驱动size配置
如图,第五组就是平台的crop,前四组是在sensor内部crop的
17.平台sensor代码参考
18.i2c bus相关配置
6765平台:
kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_i2c.c中:
19 #ifdef CONFIG_OF
20 static const struct of_device_id gof_device_id_0[] = {
21 { .compatible = IMGSENSOR_I2C_OF_DRV_NAME_0, },
22 {}
23 };
24 static const struct of_device_id gof_device_id_1[] = {
25 { .compatible = IMGSENSOR_I2C_OF_DRV_NAME_1, },
26 {}
27 };
28 static const struct of_device_id gof_device_id_2[] = {
29 { .compatible = IMGSENSOR_I2C_OF_DRV_NAME_2, },
30 {}
31 };
32 #endif
93 #define IMGSENSOR_I2C_OF_DRV_NAME_0 "mediatek,camera_main"
94 #define IMGSENSOR_I2C_OF_DRV_NAME_1 "mediatek,camera_sub"
95 #define IMGSENSOR_I2C_OF_DRV_NAME_2 "mediatek,camera_main_two"
如上,gof_device_id_0 1 2分别对应
IMGSENSOR_I2C_DEV_0,
IMGSENSOR_I2C_DEV_1,
IMGSENSOR_I2C_DEV_2,
而mediatek,camera_main,是由dws生成的cust.dtsi决定的:
如果dws中:
CAMERA_MAIN配置为channal 2,那么,生成的dtsi会是:
&i2c2 {
camera_main_mtk:camera_main@6c {
compatible = "mediatek,camera_main";
reg = <0x6c>;
status = "okay";
};
CAMERA_MAIN2配置为channal 6,那么,生成的dtsi会是:
&i2c6 {
camera_main_two_mtk:camera_main_two@2d {
compatible = "mediatek,camera_main_two";
reg = <0x2d>;
status = "okay";
};
如果有5颗摄像头呢?显然dws不能满足。所以可以得到以下结论:
点亮时,先看几颗camera的i2c总线,用了那几个,如2和4和6,当然也有公用的
然后在dws中,配置MAIN,SUB,MAIN2为 2 4 6 channal(也可以642,要把用到的配上)
这样一来,IMGSENSOR_I2C_DEV_0 1 2 就分别对应
i2c 2 4 6
然后imgsensor_cfg_table.c 中,根据每个sensor的实际情况,选择 IMGSENSOR_I2C_DEV
在6765原始代码中,imgsensor_cfg_table.c 中
IMGSENSOR_I2C_DEV_0 -->对应dws里配置的main的i2c_channal 2
IMGSENSOR_I2C_DEV_1 -->对应dws里配置的sub的i2c_channal 4
IMGSENSOR_I2C_DEV_2 -->对应dws里配置的main2的i2c_channal 6
如main2 在 SCL4 SDA4 即 I2C_CHANNEL_4 下,修改
IMGSENSOR_I2C_DEV_2--------->IMGSENSOR_I2C_DEV_1
同时修改dws下main 2挂在i2c_channal 4下
19.添加二供编译报错
添加二供CUSTOM_HAL_MAIN2_IMGSENSOR后,编译报错。
提示如:
vendor/mediatek/proprietary/hardware/connectivity/wlan/wpa_supplicant_8_lib/mediatek_driver_cmd_nl80211.c"
clang: error: no such file or directory: 'ov02b1b_hlt_mipi_raw"'
原因是项目ProjectConfig.mk中,基线释放过来时。在AUTO_ADD_GLOBAL_DEFINE_BY_NAME_VALU加了CUSTOM_KERNEL_MAIN2_IMGSENSOR
去掉该配置即可。
20.开机不search main3
projectconfig.mk : MTK_CAM_MAX_NUMBER_OF_CAMERA = 5 //这个宏定为贵司的sensor数量
要search main3,就需要修改这个宏为5。
sensor_idx对应:main---->0,sub---->1,main2---->2,sub2---->3,main3---->4,
要search到main3 ,就需要将MTK_CAM_MAX_NUMBER_OF_CAMERA改为5。
相关源码见 /vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp
146 MUINT max_index_of_camera = IMGSENSOR_SENSOR_IDX_SUB;
147 #ifdef MTK_CAM_MAX_NUMBER_OF_CAMERA
148 max_index_of_camera = MTK_CAM_MAX_NUMBER_OF_CAMERA - 1;
149 #endif
150
151 MY_LOGD("impSearchSensor search to %d\n", max_index_of_camera);
152 for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= max_index_of_camera; i++) {
同时需要注意,dts中,关于main 3的修改,main3对应的idx为4,所以相关配置为cam4,如:
“cam4_mclk_on”,
“cam4_mclk_off”;
21.平台支持最大camera个数
1.Projectconfig.mk
MTK_CAM_MAX_NUMBER_OF_CAMERA
2.加大
vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/drv/IHalSensor.h的
SENSOR_DEV_XXXX enum 和 IDX_XXX_CAM enum
3.加大kd_camera_feature.h
两个地方:
kernel/xxxx/drivers/misc/mediatek/imgsensor/inc/kd_camera_feature.h
与/device/mediatek/common/kernel-headers/kd_camera_feature.h
4 .dtsi配置
0 for main, 1 for sub, 2 for main2, 3 for sub2 …
关于平台最大能支持到多少个camera,见文档Android_Q_Multi_Sensor_Support_V1_1
22.工程模式
##3646633##
23. 抓串口log
(1)先插上串口线,连上设备。
串口线要飞两根线,一般来说黑色是地线,绿色是数据线,数据线接主板,rx,tx
(2)确定连的是哪个串口
ls /dev/tty*
此处假设为ttyUSB0
(3)sudo minicom -s //进入串口配置界面
修改Serial port setup一项(按a键),修改成上面对应的USB口。
有时候还需要设置 Bps/Par/Bits 速率
按Enter键,选save setup as dfl. (这样,下次再进来时,直接按sudo minicom即可)。
然后Exit,手机重启,抓取开机log
24. gpio dump
kernel-4.19/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
添加:
246 if (value < 0 || value > pf.mask)
247 return -EINVAL;
++if(desc->number == 107){
++ pr_info("-test %s desc number = %d\n",__func__,desc->number);
++ dump_stack();
++}
249 if (!pf.next) {
log会打印出:
09-09 00:14:49.295 1178 1178 E : .(0)[1178:HwBinder:829_4]w2m Jason-test mtk_hw_set_value desc number = 107
09-09 00:14:49.272 852 916 D AAL : onBacklightChanged: 157/1023 -> 155/1023(phy:620/4095)
09-09 00:14:49.272 852 916 D AAL : LABC: LABC after setTarget isSmoothBacklight=1
09-09 00:14:49.276 1186 7213 I system_server: The ClassLoaderContext is a special shared library.
09-09 00:14:49.279 1186 1347 V LightsService: setLight #0: color=#ff6a6a6a: brightnessMode=0
09-09 00:14:49.279 575 575 D android.hardware.lights-service.mediatek: write 106 to /sys/class/leds/lcd-backlight/brightness, result: 0
09-09 00:14:49.283 1186 7213 I system_server: The ClassLoaderContext is a special shared library.
09-09 00:14:49.296 1178 1178 W -(0)[1178:HwBinder:829_4]CPU: 0 PID: 1178 Comm: HwBinder:829_4 Tainted: P W O 4.19.127-g370b1dcf0-dirty #24
09-09 00:14:49.298 1178 1178 W -(0)[1178:HwBinder:829_4]Hardware name: MT6765V/WB (DT)
09-09 00:14:49.299 1178 1178 W -(0)[1178:HwBinder:829_4]Call trace:
09-09 00:14:49.299 1178 1178 W : -(0)[1178:HwBinder:829_4] dump_backtrace+0x0/0x198
09-09 00:14:49.300 1178 1178 W : -(0)[1178:HwBinder:829_4] show_stack+0x20/0x2c
09-09 00:14:49.301 1178 1178 W : -(0)[1178:HwBinder:829_4] dump_stack+0xb8/0xf0
09-09 00:14:49.302 1178 1178 W : -(0)[1178:HwBinder:829_4] mtk_hw_set_value+0x1e8/0x1f0
09-09 00:14:49.302 1178 1178 W : -(0)[1178:HwBinder:829_4] mtk_pconf_group_set+0x250/0x29c
09-09 00:14:49.303 1178 1178 W : -(0)[1178:HwBinder:829_4] pinconf_apply_setting+0xb8/0x100
09-09 00:14:49.304 1178 1178 W : -(0)[1178:HwBinder:829_4] pinctrl_commit_state+0x90/0x138
09-09 00:14:49.305 1178 1178 W : -(0)[1178:HwBinder:829_4] pinctrl_select_state+0x30/0x44
09-09 00:14:49.306 1178 1178 W : -(0)[1178:HwBinder:829_4] gpio_release+0x98/0xf4
09-09 00:14:49.307 1178 1178 W : -(0)[1178:HwBinder:829_4] imgsensor_hw_release_all+0x2c/0x48
09-09 00:14:49.307 1178 1178 W : -(0)[1178:HwBinder:829_4] imgsensor_release+0x90/0xf0
09-09 00:14:49.308 1178 1178 W : -(0)[1178:HwBinder:829_4] __fput+0xbc/0x1a4
09-09 00:14:49.309 1178 1178 W : -(0)[1178:HwBinder:829_4] ____fput+0x1c/0x28
09-09 00:14:49.309 1178 1178 I -(0)[1178:HwBinder:829_4]mtk_leds backlight_debug_log(170): [BL] Set Backlight directly T:98.996,L:110 map:110 T:99.14,L:109 map:109 T:99.31,L:108 map:108 T:99.49,L:107 map:107 T:99.66,L:106 map:106
09-09 00:14:49.310 1178 1178 W : -(0)[1178:HwBinder:829_4] task_work_run+0x84/0xa4
09-09 00:14:49.313 1178 1178 W : -(0)[1178:HwBinder:829_4] do_notify_resume+0x3f8/0x23e4
09-09 00:14:49.314 1178 1178 W : -(0)[1178:HwBinder:829_4] work_pending+0x8/0x10
可以大致看出,107口是在imgsensor_release出被拉低的
25. gpio配置一直为高
在上下电配置中:
1 SENSOR_DRVNAME_GC2375B_MIPI_RAW,
252 {
253 {PDN, Vol_High, 0},
254 {DOVDD, Vol_1800, 1},
255 {DVDD, Vol_1100, 1},
256 {AVDD, Vol_2800, 1},
257 {SensorMCLK, Vol_High, 1},
258 {PDN, Vol_Low, 3},
259 },
下电时,倒回来执行,理论上会拉高,但实际硬件测量,发现是一直低的。
如上条,dump gpio口,发现是在relase时被拉低,代码在
/kernel4.19/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/gpio/gpio.c中
gpio_release(void *pinstance)
会将所以gpio口拉低,如果需要将它拉高,就可以在这里操作
for (i = GPIO_CTRL_STATE_CAM0_PDN_L;
i < GPIO_CTRL_STATE_MAX_NUM;
i += 2) {
//add for 2m gc2375 power off(PWD)
if(i == GPIO_CTRL_STATE_CAM2_PDN_L){
pr_info("%s : w2m current isCamPDN %d ,continue! ", __func__,i);
mutex_lock(&pinctrl_mutex);
if (gpio_pinctrl_list[i].ppinctrl_lookup_names != NULL &&
pgpio->ppinctrl_state[i] != NULL &&
!IS_ERR(pgpio->ppinctrl_state[i]) &&
pinctrl_select_state(pgpio->ppinctrl,
pgpio->ppinctrl_state[i-1])) {
pr_info(
"%s : pinctrl err, PinIdx %d name %s\n",
__func__,
i,
gpio_pinctrl_list[i].ppinctrl_lookup_names);
}
mutex_unlock(&pinctrl_mutex);
continue;
}
//add for 2m gc2375 power off(PWD)
mutex_lock(&pinctrl_mutex);
if (gpio_pinctrl_list[i].ppinctrl_lookup_names != NULL &&
pgpio->ppinctrl_state[i] != NULL &&
!IS_ERR(pgpio->ppinctrl_state[i]) &&
pinctrl_select_state(pgpio->ppinctrl,
pgpio->ppinctrl_state[i])) {
pr_info(
"%s : pinctrl err, PinIdx %d name %s\n",
__func__,
i,
gpio_pinctrl_list[i].ppinctrl_lookup_names);
}
mutex_unlock(&pinctrl_mutex);
}
return ret;
主要逻辑是,当i == GPIO_CTRL_STATE_CAM2_PDN_L,即对pdn拉低操作时,将i-1,对应的就是GPIO_CTRL_STATE_CAM2_PDN_H,
拉高,即
pinctrl_select_state(pgpio->ppinctrl,pgpio->ppinctrl_state[i-1]))
再continue掉这次循环。
26.读id 冲突
问题现象:
景深与广角同时插上时,开机读景深的id会100%失败,超时10几秒。
单独插上,都没问题。
单独kill掉camhalserver进程,读id就正常
分析过程
第一阶段:
景深与广角三路电都是公用(avdd,iovdd),同一条i2c bus上面。
景深没有dvdd,但奇怪的是,如果给景深也上dvdd,读id冲突的问题就解决了。
但这样解决了100%失败的问题,后面产线又报出这样的问题,3%左右的机器是必现的。
第二阶段:
再次拿到能100%复现的机器,排除原因。
如果读景深id时,不去调用读id的i2c函数,直接return ture,就是正常的。所以肯定是i2c的问题。
景深,广角同一bus上面,kill掉进程,就能正常读,不冲突。
kill进程与开机的区别是什么呢?
初始化状态不同,难道是广角把i2c占用了?
排查发现,广角的reset在dws里面被默认拉高了,所以广角在景深上电时,也工作了,hold住了i2c,导致读错。
修改dws 广角的reset脚默认状态out_high为false。
27.待机af漏电
退出相机后,待机电流下不去
排查发现af供电异常,应是af没有下电
使用dw9800w。查看datasheet
下电后,应将vcm切换为power down mode。
即在DW9800WAF_Release函数中,添加对0x02地址写0x01
int i4RetValue = 0;
char puSuspendCmd9[2] = {(char)(0x02), (char)(0x01)};
LOG_INF("af release !!\n");
if (*g_pAF_Opened == 2)
LOG_INF("Wait\n");
if (*g_pAF_Opened) {
LOG_INF("Free\n");
i4RetValue = i2c_master_send(g_pstAF_I2Cclient, puSuspendCmd9, 2);
28.动态调试Scenario
adb shell setprop vendor.debug.cameng.force_sensormode 0
设置设个属性会强制选择预览setting
adb shell logcat | grep -E “select size|setScenario|scenario_id =”
02-23 01:09:50.685 941 1393 I mtkcam-SensorSettingPolicy: select size(3264x2448)@30 sensorMode:1 hdrSensorMode:0 hdrHalMode:0, hfpsMode:0
02-23 01:09:50.781 941 28312 D ImgSensorDrv: [setScenario][setScenario]DevID = 3, m_LineTimeInus = 13172 Scenario id = 1, PixelClk = 280000000, PixelInLine = 3688, Framelength = 2530
02-23 01:12:28.082 30798 30798 E : .(6)[30798:HwBinder:941_A]s5kjn1_qt_camera_sensor[control] scenario_id = 0
[control] scenario_id =
这个是在驱动.c里面打印的
1693 static kal_uint32 control(enum MSDK_SCENARIO_ID_ENUM scenario_id,
1694 MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,
1695 MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)
1696 {
1697 LOG_INF("scenario_id = %d\n", scenario_id);
这个定义如下
82 enum MSDK_SCENARIO_ID_ENUM {
83 MSDK_SCENARIO_ID_CAMERA_PREVIEW = 0,
84 MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG,
85 MSDK_SCENARIO_ID_VIDEO_PREVIEW,
86 MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO,
87 MSDK_SCENARIO_ID_SLIM_VIDEO,
88 MSDK_SCENARIO_ID_CUSTOM1,
89 MSDK_SCENARIO_ID_CUSTOM2,
29.gsi屏蔽camera
vendor/mediatek/proprietary/hardware / mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp
中:
添加头文件:
#include <cutils/properties.h>
另外,添加条件
/*search sensor using 8mA driving current*/
pSeninfDrv->setAllMclkOnOff(ISP_DRIVING_8MA, TRUE);
pSensorDrv->init();
MUINT max_index_of_camera = IMGSENSOR_SENSOR_IDX_SUB;
#ifdef MTK_CAM_MAX_NUMBER_OF_CAMERA
max_index_of_camera = MTK_CAM_MAX_NUMBER_OF_CAMERA - 1;
#endif
//add
char propValue[PROPERTY_VALUE_MAX] = {'\0'};
property_get("ro.product.name", propValue, "nullptr");
if(strstr(propValue,"gsi"))
{
MY_LOGW("gsi test expose 2 sensors: 0 ~ 1 \n");
max_index_of_camera = 1;
}
//end
30.isp_driving_current mclk的驱动电流相关及配置
sensor driver中:
.isp_driving_current = ISP_DRIVING_8MA, /* mclk driving current */
是用来设置mclk的驱动电流的,
需要增加mclk的驱动电流可以直接设置.isp_driving_current
如下语句,在设置mclk是会获取到isp_driving_current设置的值
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensor.control.cpp
生效的是pSeninfDrv->setMclkIODrivingCurrent,SensorDrivingCurrent这个值就是驱动中配置的。
749 MINT HalSensor::setSensorMclkDrivingCurrent(IMGSENSOR_SENSOR_IDX sensorIdx)
750 {
751 MINT32 ret = 0;
752 MUINT32 InputCurrent;
753
754 SensorDrv *const pSensorDrv = SensorDrv::get();
755 InputCurrent = (uint32_t)sensorDrvInfo[(uint32_t)sensorIdx].info.SensorDrivingCurrent;
756
757 #ifdef MCLK_DRIVE_CURRENT_BY_PINCTRL
758 ret = pSensorDrv->sendCommand(sensorIdx, CMD_SENSOR_SET_DRIVE_CURRENT, (MUINTPTR)&InputCurrent);
759 #else
760
761 #ifdef CONFIG_MTK_CAM_SECURE
762 SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance(HalSensorList::singleton()->querySecureState());
763 #else
764 SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance();
765 #endif
766
767 MUINT32 mclkSrc;
768
769 pSensorDrv->sendCommand(sensorIdx, CMD_SENSOR_GET_MCLK_CONNECTION, (MUINTPTR)&mclkSrc);
770 ret = pSeninfDrv->setMclkIODrivingCurrent((EMclkId)mclkSrc, sensorDrvInfo[(uint32_t)sensorIdx].info.SensorDrivingCurrent);
771 pSeninfDrv->destroyInstance();
772 #endif
773
774 if (ret < 0) {
775 MY_LOGE("The driving current for cam%d is wrong", sensorIdx);
776 }
777
778 return ret;
779 }
而MCLK_DRIVE_CURRENT_BY_PINCTRL这个宏只会在某些平台定义,最后会下到
kernel-4.14/drivers/misc/mediatek/imgsensor/src/mt6768/camera_hw/mclk.c中的__mclk_set_drive_current。
struct MCLK_PINCTRL_NAMES mclk_pinctrl_list[MCLK_STATE_MAX_NUM] = {
{"off"},
{"2mA"},
{"4mA"},
{"6mA"},
{"8mA"},
};
这个就需要在某些平台去配置一下了
ret_snprintf = snprintf(str_pinctrl_name,
sizeof(str_pinctrl_name),
"cam%d_mclk_%s",
i,
mclk_pinctrl_list[j].ppinctrl_names);
最后匹配下来就是
camera0_mclk_2mA //4 6 8 ma
camera0_mclk_off
然后dtsi中,按照平台demo配置
camera0_mclk_2mA: camera0_mclk_2mA@gpio100 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO100__FUNC_CMMCLK1>;
drive-strength = <MTK_DRIVE_2mA>;
};
};
camera0_mclk_4mA: camera0_mclk_4mA@gpio100 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO100__FUNC_CMMCLK1>;
drive-strength = <MTK_DRIVE_4mA>;
};
};
camera0_mclk_6mA: camera0_mclk_6mA@gpio100 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO100__FUNC_CMMCLK1>;
drive-strength = <MTK_DRIVE_6mA>;
};
};
camera0_mclk_8mA: camera0_mclk_8mA@gpio100 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO100__FUNC_CMMCLK1>;
drive-strength = <7>;
};
};
kernel-4.14/include/dt-bindings/pinctrl/mt6853-pinfunc.h
这个目录下,就对应dts中的pinmux =
31.平台端otp size问题
读取平台端otp时,报错
: .(6)[4520:camerahalserver]CAM_CAL[EEPROM_drv_ioctl] Error!! not support address >= 0x2000!!
发现是size超了,
排查发现:
mtk 6765平台,如果不配置这个
{S5KJN1_QT_P410AE_SENSOR_ID, 0xA0, Common_read_region},
{IMX686_SENSOR_ID, 0xA0, Common_read_region, MAX_EEPROM_SIZE_16K},
默认会走8k的
32.isp版本
/android/vendor/mediatek/proprietary/hardware/mtkcam/aaa/aaa.mk
33.mtk mfnr
具体参考文档004_Capture-MFNR-Remosaic-ZSL.pdf
MTK_CAM_MFB_SUPPORT = 3 ===>如果支持 MFNR,一般设为 3
metadata 新版本已包含
开log:adb shell setprop vendor.mfll.log_level 3
关键字:Mfll apply =|negotiate] realIso = |collected request|callback request| have collected all requests|removeShotInfo|Mfll}queryStrategy|future allocate
34.mtk tag与android tag转换
/vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/client/TagMap.h
35.camera id引脚二供兼容
当camera 无otp时,要区分一二供,通常根据camera id来区分
原理图如下:
代码里面:
dtsi里面,在&kd_camera_hw1 {下面添加
gpio-cammain2-id = <&pio 21 0x0>;
驱动.c里面添加头文件
#include <linux/gpio.h>
#include <linux/of_gpio.h>
同时,在get_imgsensor_id中添加
kal_uint8 i = 0;
kal_uint8 retry = 2;
//add
unsigned int pDTS_sensors_id;
int gpio_value, ret = -EIO;
struct device_node *of_node = of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");
pDTS_sensors_id = of_get_named_gpio(of_node, "gpio-cammain2-id", 0);
pr_err("cam2_hw_id=%d %d\n",pDTS_sensors_id,__LINE__);
if (pDTS_sensors_id < 0)
pr_err("%s get gpio = %d failed.\n", __func__, pDTS_sensors_id);
ret = gpio_request(pDTS_sensors_id, "gpio-cammain2-id");
if (ret < 0) {
pr_err("request camera gpio id failed.\n");
}
ret = gpio_direction_input(pDTS_sensors_id);
if (ret < 0) {
pr_err(" gpio_direction_input failed");
}
gpio_value = gpio_get_value(pDTS_sensors_id);
gpio_free(pDTS_sensors_id);
pr_err("wrrt gc02m1b_hw_id status=%d %d\n",gpio_value,__LINE__);
36.cts测试中log打印
如CameraTestUtils.java中
if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
这个VERBOSE的值
103 private static final String TAG = “CameraTestUtils”;
104 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
就可以这样设置
adb shell setprop log.tag.CameraTestUtils VERBOSE
37.PMIC调试
adb root
adb shell
cd /sys/devices/platform/1000d000.pwrap/1000d000.pwrap:main_pmic/mt-pmic
echo 1946>pmic_access
cat pmic_access (会是0x0b)
echo 1946 0x0a>pmic_access
echo 1946>pmic_access
cat pmic_access (变成0x0a后,再测量vio28或者看一下待机电流)
每次cat 状态,都要先echo一下地址
https://online.mediatek.com/FAQ#/SW/FAQ18183
参考FAQ即可。
37.af漏电一直为高
项目af供电使用vio28 ,并不是给camera专用的
现象如下:
不配置dts,马达任然可以动。硬件测量,开机vio28就上电了,2.8v。
待机时,拔掉camera,整机电流会下降0.3ma左右。
分析是平台将这路电配置为默认高了。
但dst里面,并没有always on。
最后,在vendor / mediatek/proprietary/bootable/bootloader/preloader/platform/mt6765/src/drivers/pmic.c里面
将其拉低写0。
U32 pmic_init (void)函数里面
/* default disable smart reset, enablt it by RGU driver */
pmic_config_interface(PMIC_RG_SMART_RST_MODE_ADDR, 0x0,
PMIC_RG_SMART_RST_MODE_MASK,
PMIC_RG_SMART_RST_MODE_SHIFT);
pmic_config_interface(PMIC_RG_SMART_RST_SDN_EN_ADDR, 0x0,
PMIC_RG_SMART_RST_SDN_EN_MASK,
PMIC_RG_SMART_RST_SDN_EN_SHIFT);
// DATE20220428, V820,af power off
#if defined(V820_CAMERA_AF_OFF)
pmic_config_interface(PMIC_RG_LDO_VIO28_EN_ADDR, 0x0,
PMIC_RG_LDO_VIO28_EN_MASK,
PMIC_RG_LDO_VIO28_EN_SHIFT);
#endif
// WIKO END
print("[PMIC]Init done\n");
return ret_code;
}
PMIC_RG_LDO_VIO28_EN_ADDR这个在pmic芯片或者代码里面都能找到
38.mipi 速率
有两个概念:mipi data rate和mipi_pixel_rate
- mipi data rate:就是MIPI_output_speed,是每lane的速率
单位是Mbps/lane 即million bits per second,注意这里是bits,就是位
就多少百万位 每秒,如果换成字节就除以8 :x÷8 就MB/s
如 1152.00 Mbps/lane 1152÷8=144 MB/s
- mipi_pixel_rate:
mipi_pixel_rate = mipi data rate (bits/s)lane/pixel_depth
ex. 1.5g bits per lane, 4 lane, raw10 = 1.5G4/10= 600Mpps
这个Mpps全称是million packet per second 的含义是百万包每秒,指包转发率 ,因为这个是raw10的sensor,使用pixel_depth就是10
那么1152Mbps换成mipi_pixel_rate就是:1152*4/10=460.8Mpps 即460800000
这个填在mtk驱动的.mipi_pixel_rate
在高通平台,mipi_pixel_rate这个值叫op_pixel_clk表示每秒VFE处理的数据量/像素个数,op_pixel_clk = (sensor输出实际比特率) / bits_per_pixel,比如,如果MIPI DDR 时钟值(Sensor MIPI 的时钟lane频率)为300MHz,同时sensor使用4 lane传输数据,每一个lane的数据率是300×2=600MHz(因为MIPI信号进入高速模式后,clock 上升沿和下降沿都会发送数据,所以会x2)。因此,总数据率为600×4=2400MHz,对于10bit的bayer sensor,op_pixel_clk的值可设置为2400/10 = 240MHz。
MHz是频率单位,Mbps是速率单位,MIPI信号进入高速模式后,clock 上升沿和下降沿都会发送数据,所以会有一个x2的关系
关于射频干扰:
注意这个配置不能和天线初一同一个频段,或者说这个频率的倍数不能落到天线的频段里面去,否则就会对天线干扰。
计算方法是这样子的:比如说,我们的op_pixel_clk配置的是254.4,那么mipi data rate: each lane data就是(254.4 * 10) / 4 = 636,接下来对636这个值除2,这个值318就是硬件工程师测量出来的那个值,这个值的倍频不能落在下面的区间内,1 2 3 4 5 6 7 8 9 等等倍数。
全尺寸配的是 280 算出来 (280/4)*10 = 700 700/2 = 350 实际测试的是350MHZ
39.流程log关键字
camera service 打开相机:CameraService::connect
打开相机: session::onOpenLocked
上电与init寄存器初始化 :MtkCam/HalSensor: [powerOn
配流:session::configureStreams_3_6] +
下面几行就是配流size,user可输出session::checkStream
驱动执行preview等寄存器操作,开流操作:开始 configure Scenario=
完成> setScenario][setScenario
或者 SET_STREAMING_RESUME
request 到达底层:session::processCaptureRequest] -> 1st request
底层出第一帧:sendFrameToRootNodes] r0 frameNo:0
往上送 releaseAction
关闭相机: session::flush
与 session::close
cmp=com.myos.camera|CameraApp onCreate star|CameraApp onCreate start|open camera…|camera opened|create capture session execute…|session configured, time|first set preview capture request|first frame arrived
CameraService::connect|session::onOpenLocked|MtkCam/HalSensor: [powerO|configure Scenario=|setScenario][setScenario|session::processCaptureRequest] -> 1st request|sendFrameToRootNodes] r0 frameNo:0|SET_STREAMING_RESUME
40.vbanking 计算
.pclk = 480000000,/* record different mode’s pclk /
.linelength = 4896,/ record different mode’s linelength /
.framelength = 3260,/ record different mode’s framelength /
.startx = 0,/ record different mode’s startx of grabwindow /
.starty = 0,/ record different mode’s starty of grabwindow /
.grabwindow_width = 4208,/ record different mode’s width of grabwindow /
.grabwindow_height = 3120,/ record different mode’s height of grabwindow */
.mipi_data_lp2hs_settle_dc = 85,
.max_framerate = 300,
.mipi_pixel_rate = 448000000,
vbanking time = (3260-3120)*4896/480000000 =0.001428s= 1.428ms
即vbanking time=(framelength-grabwindow_height )* linelength /pclk
41.sensor gain配置
老平台,需确认set_gain中的倍数
static kal_uint16 set_gain(kal_uint16 gain)
{
//gain = 64 = 1x real gain.
kal_uint16 reg_gain;
LOG_INF("set_gain %d \n", gain);
if (gain < BASEGAIN || gain > 64 * BASEGAIN) {
LOG_INF("Error gain setting");
if (gain < BASEGAIN)
gain = BASEGAIN;
else if (gain > 64 * BASEGAIN)
gain = 64 * BASEGAIN;
}
reg_gain = gain2reg(gain);
spin_lock(&imgsensor_drv_lock);
imgsensor.gain = reg_gain;
spin_unlock(&imgsensor_drv_lock);
LOG_INF("gain = %d , reg_gain = 0x%x\n ", gain, reg_gain);
write_cmos_sensor(0x0204, (reg_gain&0xFFFF));
return gain;
} /* set_gain */
其中BASEGAIN是0x40,这个是平台定义的,所以 要reg_gain = gain2reg(gain); /2转换
64-------》则需要在datasheet确认。
另外,V1_1平台,有如下配置需确认:
.min_gain = 64, /*1x gain*/
.max_gain = 1024, /*16x gain*///如是64倍gain,那么 就应该写64*64
.min_gain_iso = 100,
.gain_step = 2,
.exp_step = 2,
.gain_type = 2,
其中gain_step就是调试的每一段的值。如:64是一倍gain,128是两倍,那么gain_step=2 即32,他们就支持64+32+32+32这种,1倍,1.5倍,2倍,2.5倍
gain_type就与sensor强相关,如上图
42.af相关配置以及metadata
android.lens.focusDistance就是手动模式下,apk下发的值
android.lens.focusDistance (80003): float[1] [19.20000076 ]
这个是底层配置的范围,此时是0~20,但正常最近应该是10cm对焦距离的(看otp手册),某些可能会烧录在otp
android.lens.info.minimumFocusDistance (90005): float[1] [20.00000000 ]
即
CONFIG_METADATA_BEGIN(MTK_LENS_INFO_MINIMUM_FOCUS_DISTANCE)
CONFIG_ENTRY_VALUE((1.0/0.1), MFLOAT) // 10 cm min focus distance
CONFIG_METADATA_END()
它与另一个tag有关联:
另外一个tag,就是远焦距离
CONFIG_METADATA_BEGIN(MTK_LENS_INFO_HYPERFOCAL_DISTANCE)
CONFIG_ENTRY_VALUE((1.0/10.0), MFLOAT) // 10 m hyperfocal distance
CONFIG_METADATA_END()
谷歌官方介绍:
另一个tag,我们配置的为UNCALIBRATED,那就不会去报告
//==========================================================================
CONFIG_METADATA_BEGIN(MTK_LENS_INFO_FOCUS_DISTANCE_CALIBRATION)
CONFIG_ENTRY_VALUE(MTK_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED, MUINT8)
CONFIG_METADATA_END()
因为我们配置的UNCALIBRATED,实际并不会报告这个属性。
如果是配置另外两个,这个就表示远焦,单位(1/m)
那么(1.0/10.0)就是10m
43.rrzo mdp
logcat | grep -E “CAM_RRZ_CTRL::_config+|startMdp”
06-22 17:55:45.650 957 15269 D ifunc_cam: [_config] [0x0]:CAM_RRZ_CTRL::_config+ cq:0x0,page:0x1,rrz_in_w/h(4080/3072),rrz_crop_x/y/fx/fy/w/h(0/0/0/0/4080/3072),rrz_out_w/h(1280/976),rlb_offset(0),rrz_h/v_step(104504/103210),vbn/dbn/bin(0/0/0),dbg(4080/3072)
06-22 17:55:45.659 957 15315 D MdpMgr : [_startMdp] +sceID(0),cqPa(0x49c24000)-Va(0x70d68ce000),tpipVa(0x70d6429000)-Pa(0x49e80000),isWaitB(1),cqIndx(0/0/0/6),venc(0),(va: 0x70d6429000), srcFt(0x2205),W(1280),H(976),stride(2400,0),size(0x23be00-0x0-0x0),VA(0x ffff),PA(0x47a00000),plane(1),Stmtype(1)
也可以看RMX,打印比较少
LMVTuning: [p1TuningNotify][Cam::0]M(0)enLMV(1):TG(4080,3072),RRZ In(4080,3072),RRZ crop x/y(0,0),RRZ crop w/h(4080,3072),RMX(1568,1184),HBIN(784,1184),pixelMode(1),YUV(0)
或者
vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/policy/config/P1HwSettingPolicy.cpp中的
mtkcam-P1HwSettingPolicy: [configP1HwSetting]
06-24 11:32:14.888 26451 3030 W mtkcam-P1HwSettingPolicy: [evaluateDeviceRawBitDepth] By default bitdepth:10
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] max_rrzo_size: target size(2560x1928)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] sensor size: target size(4080x3072)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] target rrzo stream: target size(1560x1174)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] eis lower bound limitation: target size(1560x1174)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] preview upper bound limitation: target size(1560x1174)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] rrzo size(1560x1174)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [configP1HwSetting] sensor size upper bound limitation: target size(1568x1184)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: aligned rrzo size(1568x1184)
06-24 11:32:14.888 26451 3030 D HalIspImp: [createInstance] sensorIdx(0) mtkcam-P1HwSettingPolicy
06-24 11:32:14.888 26451 3030 D HalIspImp: [destroyInstance]+ sensorIdx(0) User(mtkcam-P1HwSettingPolicy)
06-24 11:32:14.888 26451 3030 D mtkcam-P1HwSettingPolicy: [queryRecommendResizeMaxRatio] Resize-Ratio-Percentage 25 for isp quality
06-24 11:32:14.888 26451 3030 I mtkcam-P1HwSettingPolicy: { .imgoAlloc={ format:0x2201 4080x3072 } .imgoDefaultRequest={ format:0x2201 4080x3072 } .rrzoDefaultRequest={ format:0x2205 1568x1184 } .rssoSize=288x512 .pixelMode=1 .usingCamSV=0 }
user版本看: rrzoDefaultRequest
rrzoDefaultRequest|session::checkStream|CameraService::connect
44.调用栈打印
- Android.mk中添加
LOCAL_SHARED_LIBRARIES += libutilscallstack
- 头文件中添加
#include <utils/CallStack.h>
- 打印
+ android::CallStack stack;
+ stack.update();
+ stack.log("getStack");
方法二:
1.在AAOBufMgr.cpp文件下加头文件#include
2.在updateInfo()函数中(函数开头处)加
Utils::dumpCallStack(“hihi,updateInfo here”);
3.updateInfo()所在路径下的Android.mk文件中加入依赖库
LOCAL_SHARED_LIBRARIES +=
libmtkcam_stdutils
45 dump 符号表
22826 22826 F DEBUG : #02 pc 000000000000496c /data/app/~~66Wtd734q-oRZd0ZffzWaA==/com.myos.camera-jdhpG01fRANlNlD7yfXQAQ==/base.apk!libPluginManagerJni.so (getParameter(_JNIEnv*, _jobject*, _jstring*, _jstring*)+136)
addr2line -C -f -e android/out/target/product/v820/system/lib64/libPluginManagerJni.so 000000000000496c
能出现报错行
postByteData(_JNIEnv*, _jobject*, _jstring*, _jstring*, _jbyteArray*)
/home/android/soft/android-sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/jni.h:847
46 cts FOV测试
首先看一下cts中计算fov的逻辑
b.修改 config_static_metadata.lens.s5kjn1mipiraw.h
CONFIG_METADATA_BEGIN(MTK_LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
CONFIG_ENTRY_VALUE(4.23ff, MFLOAT)
CONFIG_METADATA_END()
c. 修改config_static_metadata.sensor.s5kjn1mipiraw.h
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_PHYSICAL_SIZE) // mm
CONFIG_ENTRY_VALUE(5.22f, MFLOAT)
CONFIG_ENTRY_VALUE(4.49f, MFLOAT)
CONFIG_METADATA_END()
镜头宽高:Resolution*Pixel Size
宽(d):8160*0.64=5222 --> 约5.22mm
高(f):6144*0.64=3932 --> 约4.22mm
d. 角度计算公式:
angel of view = 2 * arctangent(d/2f) //此例子中计算可知Report FOV为:63.4°
而谷歌代码中,计算fov是:
if (horizFov != NULL) {
*horizFov = 180 / M_PI * 2 *
atanf(horizCropFactor * sensorSize.data.f[0] /
(2 * fastInfo.defaultFocalLength));
}
if (vertFov != NULL) {
*vertFov = 180 / M_PI * 2 *
atanf(vertCropFactor * sensorSize.data.f[1] /
(2 * fastInfo.defaultFocalLength));
}
而horizCropFactor与vertCropFactor的计算 ,依赖两个tag
ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE与ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE
即pixel_array_size
与active_array_size
而sensorSize.data[0]与1,就是ANDROID_SENSOR_INFO_PHYSICAL_SIZE即physical_size
camera_metadata_ro_entry_t pixelArraySize =
staticInfo(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, 2, 2);
camera_metadata_ro_entry_t activeArraySize =
staticInfo(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 2, 4);
camera_metadata_ro_entry_t sensorSize =
staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
horizCropFactor *= (static_cast<float>(fastInfo.arrayWidth) /
pixelArraySize.data.i32[0]);
vertCropFactor *= (static_cast<float>(fastInfo.arrayHeight) /
pixelArraySize.data.i32[1]);
这三个tag,对应mtk的tag为:
_IMP_TAGCONVERT_( ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, MTK_SENSOR_INFO_PIXEL_ARRAY_SIZE)\
//全像素阵列的物理尺寸。
_IMP_TAGCONVERT_( ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION)\
//在应用任何几何失真校正后,对应于活动像素的图像传感器区域。这是表示在应用任何几何校正后传感器的活动区域(即实际接收来自场景的光的区域)大小的矩形,应视为任何图像输出的最大像素大小除了原始格式之外的格式。
_IMP_TAGCONVERT_( ANDROID_SENSOR_INFO_PHYSICAL_SIZE, MTK_SENSOR_INFO_PHYSICAL_SIZE)\
//全像素阵列的尺寸,可能包括黑色校准像素。覆盖 android.sensor.info.physicalSize区域的图像传感器全像素阵列的像素数。这表示该传感器产生的原始缓冲区的完整像素尺寸。
详见
ACTIVE_ARRAY_SIZE
理论上在metadata中配置
但实际pixel_array_size
与active_array_size
没生效,physical_size
是生效的,查看代码:hardware/mtkcam/drv/src/sensor/common/v1_1/HalSensorList.cpp,发现这两个tag实际去驱动中拿的,会覆盖我们配置的值。
这里,mtk v1与v1_1就有区别了。
v1:pixel_array_size
=8160 active_array_size
=4080
而v1_1平台::pixel_array_size
=4080 active_array_size
=4080
所以在v1平台:
pixel_array_size=8160,而active_array_size=4080
horizCropFactor =4080/8160=0.5
因为
180 / M_PI * 2 * atanf(horizCropFactor * sensorSize.data.f[0] / (2 * fastInfo.defaultFocalLength));
horizCropFactor 为0.5,相当于将sensorSize.data即physical_size
缩小了一半
根据angel of view = 2 * arctangent(d/2f)
fov计算出来就会比实际小一半,即31.7°
那么,cts测试就有如下方案去规避:
1.在framework中,修改horizCropFactor 为1
2.底层将physical_size扩大两倍,(安兔兔传感器尺寸会计算有误)
v1_1平台:
此时底层pixel_array_size与active_array_size都为4080,计算出来是horizCropFactor=1。但因为模组要按照50m计算,双摄会有fov异常
那么,cts测试就有如下方案去规避:
1.将底层pixel_array_size与active_array_size都改为8160(直接改setting,capture配置成50m),那么就horizCropFactor 为1,按照50m计算的fov就没有问题了
2.计算模组的fov时,因为pixel_array_size是4080,那么,将physical_size缩小一半,4080*0.64=2.611。(安兔兔传感器尺寸会计算有误,双摄会出现辅摄fov变小的现象)
采用第一张方案后,引发新的cts fail项:
即active_array_size太大,yuv size太小
根据谷歌的定义,有高像素的配置方法:
但这是api31的,查看mtk底层的配置tagMap.h,并不支持这些tag。
47 双摄硬同步
Master和Slave通过FSIN信号线连接着。并且,Master在开始出每一帧数据的同时,都会给Slave发一个FSYNC信号;Slave接收到FSYNC信号,才开始出数据。这样就实现了硬件帧同步。
硬件帧同步要求:通过示波器抓取mipi波形,要求Mater和Slave的两帧sof相差小于100us
驱动setting里面可控制VSYNC out是高有效还是低有效,具体根据slave sensor需匹配的信号。
setting需sensor厂提供。需主摄作为master时的寄存器与辅摄作为slave时的寄存器setting。
如:
上图中,FSYNC信号采用的是垂直同步类型,即VSYNC方式;另外还有一种方式,是脉冲模式,即Pulse type。
- 主sensor产生Fsync,开始传输第一帧
- 当 从sensor接收到第一个 Fsync后,开始曝光并且同时读出数据。(因为第一帧没有开始曝光的信号,曝光与读出时间没有间隔)
- 当从sensor的第一帧传输完成后,就马上开始曝光第二帧,在曝光状态下,从sensor在收到第二次FSYNC时 ,开始读出数据
需要注意,这个mipi output的read时间,与逐行曝光的read时间不一样。
逐行曝光的read时间:sensor开始曝光,根据逐行曝光的概念,曝光一行就会读出一行。
mipi output的read时间:是指mipi传输这一帧的时间。
至于为什么可以控制这个时间点应该是sensor内部的某种机制控制的,可以延迟将数据打包成mipi数据包 发送出去的时间。
而控制这个时间的长短,就是通过调整曝光了
当这颗sensor做slave时,调整同步的方式有两种。
如图描述,当slave sensor的帧长小于Master-260时,会增加曝光时间,相应的读出(mipi output)时间也会增加,以达到同步效果。
另一种方式,按照理解,应该是直接丢一帧。
48 Camera lane 数的理论计算
Camera 有效像素 * ADC色彩深度 * 帧率 * (1+20%) < lane数量 * MIPI速率
- 有效像素数: 2592*1944 pixels =5,038,848
- ADC色彩深度:专业术语是色彩深度。色彩深度越高,可用的颜色就越多。10bit实际就是ADC的采集精度,在Camera中表示1个pixel的采集精度可达到210=1024。一般手机camera Sensor使用的是0bit RGB RAW,具体需参考使用的Sensor spec。
- MIPI速率:从平台design notice可得知。如6765平台,2.5Gbps。6833平台,6.5Gbps。
如5m的在6765平台(2.5Gbps):
2592 x1944×10 ×30 * (1+20%) = 1.81Gbps
1.81<2.5
所以1lane就够了。
如8m的在6765平台
3264x2448x10x30x1.2=2.87Gbps > 2.5Gbps
2.87x2=5.74Gbps,所以至少要2lane