MRESULT AeMgr::updateSensorbyI2C() {
MINT32 err = S_AE_OK;
if(m_bSetFrameRateValue) { // update frame rate m_bSetFrameRateValue = MFALSE;
AaaTimer localTimer(\m_eSensorDev, (m_3ALogEnable & EN_3A_SCHEDULE_LOG)); err = AAASensorMgr::getInstance().setPreviewMaxFrameRate((ESensorDev_T)m_eSensorDev, m_u4UpdateFrameRate_x10, m_eSensorMode); localTimer.End(); if (FAILED(err)) {
MY_ERR(\ } }
if((m_eAETargetMode == AE_MODE_AOE_TARGET) || (m_eAETargetMode == AE_MODE_MVHDR_TARGET)) { // mVHDR/iVHDR sensor control ......
} else { // normal control
if(m_bSetShutterValue) { // update shutter value
AaaTimer localTimer(\m_eSensorDev, (m_3ALogEnable & EN_3A_SCHEDULE_LOG)); err = AAASensorMgr::getInstance().setSensorExpTime((ESensorDev_T)m_eSensorDev, m_u4UpdateShutterValue);
localTimer.End();
m_bSetShutterValue = MFALSE; if (FAILED(err)) {
MY_ERR(\ } }
if(m_bSetGainValue) { // update sensor gain value
AaaTimer localTimer(\m_eSensorDev, (m_3ALogEnable & EN_3A_SCHEDULE_LOG)); err = AAASensorMgr::getInstance().setSensorGain((ESensorDev_T)m_eSensorDev, m_u4UpdateGainValue);
err = AAASensorMgr::getInstance().setSensorIso((ESensorDev_T)m_eSensorDev, m_eSensorMode, m_rAEOutput.rPreviewMode.u4RealISO); localTimer.End();
m_bSetGainValue = MFALSE; if (FAILED(err)) {
MY_ERR(\ } } }
return S_AE_OK; }
第18-26行,更新设置sensor的快门打开时间,也就是曝光时间 第28-37行,更新设置sensor的亮度的Gain值
其中m_u4UpdateShutterValue 和m_u4UpdateGainValue的值都是在前面的UpdateSensorISPParams函数中设置
看下setSensorGain函数的实现
MRESULT
AAASensorMgr::
setSensorGain(MINT32 i4SensorDev, MUINT32 a_u4SensorGain) {
MINT32 ret = S_AAA_SENSOR_MGR_OK;
......
// Set sensor gain
if(i4SensorDev == ESensorDev_Main) { ret = m_pHalSensorObj->sendCommand(NSCam::SENSOR_DEV_MAIN, SENSOR_CMD_SET_SENSOR_GAIN, (MUINTPTR)&a_u4SensorGain, 0, 0); } else if(i4SensorDev == ESensorDev_Sub) { ...... }
......
return (ret); }
MINT HalSensor::sendCommand( MUINT sensorDevIdx, MUINTPTR cmd, MUINTPTR arg1, MUINTPTR arg2, MUINTPTR arg3) {
switch (cmd) {
case SENSOR_CMD_SET_SENSOR_GAIN:
cmdId = CMD_SENSOR_SET_SENSOR_GAIN;
pSensorDrv->sendCommand((SENSOR_DEV_ENUM)sensorDevId,cmdId, arg1); break; ......
return ret; }
MINT32
ImgSensorDrv::sendCommand(
SENSOR_DEV_ENUM sensorDevId, MUINT32 cmd, MUINTPTR arg1, MUINTPTR arg2, MUINTPTR arg3 ) {
switch (cmd) {
case CMD_SENSOR_SET_SENSOR_GAIN:
FeatureId = SENSOR_FEATURE_SET_GAIN; FeaturePara[0] = *parg1; //from 10b to 6b base FeaturePara[0] >>= 4;
FeatureParaLen = sizeof(MUINT64);
pFeaturePara = (MUINT8*)FeaturePara; break;
......
err= featureControl((CAMERA_DUAL_CAMERA_SENSOR_ENUM)sensorDevId, FeatureId, (MUINT8*)pFeaturePara,(MUINT32*)&FeatureParaLen); if (err < 0) {
LOG_ERR(\ return -errno; }
......
return err; }
MINT32
ImgSensorDrv::featureControl(
CAMERA_DUAL_CAMERA_SENSOR_ENUM InvokeCamera, ACDK_SENSOR_FEATURE_ENUM FeatureId, MUINT8 *pFeaturePara, MUINT32 *pFeatureParaLen ) {
ACDK_SENSOR_FEATURECONTROL_STRUCT featureCtrl; MINT32 err = SENSOR_NO_ERROR;
......
featureCtrl.InvokeCamera = InvokeCamera; featureCtrl.FeatureId = FeatureId;
featureCtrl.pFeaturePara = pFeaturePara;
featureCtrl.pFeatureParaLen = pFeatureParaLen;
err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_FEATURECONCTROL , &featureCtrl); if (err < 0) {
LOG_ERR(\ return -errno; }
return err; }
最后调用到imgsensor_drv.cpp的featureControl函数,通过ioctl进入到kernel层,kernel层对应的sensor驱动会通过i2c设置sensor的寄存器
6. 总结
3A的初始化在DefaultCam1Device的onInit函数里面开始,主要就是初始化3A的状态管理并切换到init状态,创建了onThreadLoop 和
AFThreadFunc两个线程。onThreadLoop是3A主线程,负责接收处理命令;AFThreadFunc负责实时更新AF参数
接收到PASS1_START_ISP事件之后,Hal3A会再创建一个AESensorThreadLoop线程负责实时更新sensor的AE参数,同时还会对AWB、AE、AF进行初
始化,最后将3A状态切换到CameraPreview状态。
Pass1Node每deque一帧数据就会发出PASS1_EOF事件来更新3A,Hal3A接收到消息之后会计算ISP相关的参数并将得到的参数设置到Isp Tuning里 面
当需要更新Sensor的参数时ISP会产生一个中断,而AFThreadFunc和AESensorThreadLoop则通过一个死循环不断去捕获中断,捕获到中断之后会
让kernel层对应的驱动通过i2c设置相关的寄存器