Camera Sensor接口配置

参考资料:极客笔记
 
以ov7251的cpp接口文件为例,编译生成so库文件
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxsensordriverapi.h"
// NOWHINE ENTIRE FILE

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RegisterToRealGain
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static DOUBLE RegisterToRealGain(
    UINT registerGain)
{
    DOUBLE real_gain;
    real_gain = (DOUBLE) (((DOUBLE)(registerGain))/16.0);
    return real_gain;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RealToRegisterGain
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static UINT RealToRegisterGain(
    DOUBLE realGain)
{
    UINT reg_gain = 0;
    realGain = realGain*16.0;
    reg_gain = (UINT)realGain;
    return reg_gain;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CalculateDigitalGain
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static UINT CalculateDigitalGain(
    FLOAT totalRealGain,
    FLOAT sensorRealGain)
{
    CDK_UNUSED_PARAM(totalRealGain);
    CDK_UNUSED_PARAM(sensorRealGain);
    return 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FillExposureSettings
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CalculateExposure(                                    // 计算曝光的具体接口
    SensorExposureInfo*          pExposureInfo,            // 输出
    SensorCalculateExposureData* pCalculateExposureData)    // 平台传进来的
{
    ... ...
    pExposureInfo->analogRegisterGain   = RealToRegisterGain(pCalculateExposureData->realGain);    // 平台传进来的realGain转到寄存器的模拟gain
    pExposureInfo->analogRealGain       = static_cast<FLOAT>(RegisterToRealGain(pExposureInfo->analogRegisterGain));    // 变成register值
    pExposureInfo->digitalRegisterGain  =
        CalculateDigitalGain(pCalculateExposureData->realGain, pExposureInfo->analogRealGain);    // 平台传进来的realGain转到寄存器数字gain
    pExposureInfo->digitalRealGain      = 1.0;    // 系数
    pExposureInfo->ISPDigitalGain       =
        pCalculateExposureData->realGain /(pExposureInfo->analogRealGain * pExposureInfo->digitalRealGain);    // 还不满足,就需要ISP数字gain
    pExposureInfo->lineCount            = pCalculateExposureData->lineCount;    // 平台传入直接赋值
    ... ...
    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FillExposureSettings
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL FillExposureSettings(                        // 具体实现代码逻辑
    RegSettingsInfo*        pRegSettingsInfo,        // 输出参数
    SensorFillExposureData* pExposureData)            // 输入参数
{
    ... ...
    for (index = 0; index < pExposureData->pRegInfo->groupHoldOnSettings.regSettingCount; index++)    // 配置holdon寄存器
    {    
        pRegSettingsInfo->regSetting[regCount].registerAddr =
            pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].registerAddr;
        pRegSettingsInfo->regSetting[regCount].registerData =
            pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].registerData;
        pRegSettingsInfo->regSetting[regCount].regAddrType  =
            pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].regAddrType;
        pRegSettingsInfo->regSetting[regCount].regDataType  =
            pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].regDataType;
        pRegSettingsInfo->regSetting[regCount].delayUs      =
            pExposureData->pRegInfo->groupHoldOnSettings.regSetting[index].delayUs;
    regCount++;    // 多少个寄存器要去写
    }

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->frameLengthLinesAddr;    // 曝光相关寄存器VTS
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->frameLengthLines & 0xFF00) >> 8;
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->frameLengthLinesAddr + 1;
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->frameLengthLines & 0xFF);
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->coarseIntgTimeAddr - 1;    // line count
    pRegSettingsInfo->regSetting[regCount].registerData  = pExposureData->lineCount >> 12;
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->coarseIntgTimeAddr;
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->lineCount >> 4) & 0xFF;
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->coarseIntgTimeAddr + 1;
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->lineCount << 4) & 0xFF;
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->globalAnalogGainAddr;    // gain配置
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->analogRegisterGain & 0xFF00) >> 8;
    regCount++;

    pRegSettingsInfo->regSetting[regCount].registerAddr  = pExposureData->pRegInfo->globalAnalogGainAddr+ 1;
    pRegSettingsInfo->regSetting[regCount].registerData  = (pExposureData->analogRegisterGain & 0xFF);
    regCount++;

    for (index = 0; index < pExposureData->pRegInfo->groupHoldOffSettings.regSettingCount; index++)    // hold off配置
    {
        pRegSettingsInfo->regSetting[regCount].registerAddr  =
            pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].registerAddr;
        pRegSettingsInfo->regSetting[regCount].registerData  =
            pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].registerData;
        pRegSettingsInfo->regSetting[regCount].regAddrType  =
            pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].regAddrType;
        pRegSettingsInfo->regSetting[regCount].regDataType=
            pExposureData->pRegInfo->groupHoldOffSettings.regSetting[index].regDataType;
        regCount++;
    }

    pRegSettingsInfo->regSettingCount = regCount;    // 总共的寄存器

    if (MAX_REG_SETTINGS <= regCount)
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetSensorLibraryAPIs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID GetSensorLibraryAPIs(
    SensorLibraryAPI* pSensorLibraryAPI)
{
    pSensorLibraryAPI->majorVersion          = 1;
    pSensorLibraryAPI->minorVersion          = 0;
    pSensorLibraryAPI->pCalculateExposure    = CalculateExposure;            // 主要就是实现这两个接口,计算曝光的关系
    pSensorLibraryAPI->pFillExposureSettings = FillExposureSettings;
}

#ifdef __cplusplus
}
#endif // __cplusplus

// SensorCalculateExposureData结构体,平台传入
typedef struct SensorCalculateExposureData
{
    FLOAT realGain;    // AE算法提供过来的,TOTAL gain
    UNIT lineCount;    // 曝光时间转换成linecount
    FLOAT middleRealGain; // 针对HDR sensor,普通sensor不用care
    UINT middleLinecount;
    FLOAT shortRealGain;
    UINT shortLinecount;
    UNIT32 sensorResolutionIndex;    // xml中不同的settings,平台传入的
} SensorCalculateExposureData;

// 输出函数
typedef struct SensorExposureInfo
{
    FLOAT analogRealGain;            // 模拟gain
    UINT  analogRegisterGain;        // 模拟gain对应的值
    FLOAT digitalRealGain;            // sensor数字gain
    UINT digitalRegisterGain;        // sensor数字gain对应寄存器的值
    FLOAT shortAnalogRealGain;        // HDR sensor才有
    UINT shortRegisterGain;
    FLOAT shortDigitalRealGain;
    UINT shortDigitalRegisterGain;
    FLOAT middleAnalogRealGain;
    UINT middleRegisterGain;
    FLOAT middleDigitalRealGain;
    UINT middleDigitalRegisterGain;
    FLOAT ISPDigitalGain;            // ISP数字gain,ISP只有数字gain,没有不用填
    UINT lineCount;                // 和传过来一样
    UNIT shortLinecount;
    UINT middleLinecount;
    FLOAT sensitivityCorrectionFactor;        // sensor感光度矫正因子,tunning管理
} SensorExposureInfo;

struct SensorFillExposureData    // 填充曝光数据,输入参数数据结构
{
    SensorExposureRegInfo* pRegInfo;    // sensor的曝光寄存器信息
    UINT analogRegisterGain;        // 模拟Gain寄存器值
    UINT digitalRegisterGain;        // 数字gain寄存器值
    UNIT lineCount;                // linecount
    UNIT frameLengthLines;            // VTS
    UNIT shortRegisterGain;            // HDR相关
    UNIT shortDigitalRegisterGain;
    UNIT middleRegisterGain;
    UNIT middleDigitalRegisterGain;
    UNIT shortLineCount;
    UNIT middleLineCount;
    INT32 additionalInfo[MAX_REG_CONTROL_EXT_DATA_SIZE];    // 拓展的相关
    BOOL applyShortExposure;
    BOOL applyMiddleExposure;
    FLOAT sensitivityCorrectionFactor;        // tunning填写
    UINT32 sensorResolutionIndex;            // 娜一组配置
} SensorFillExposureData;

struct RegSettingsInfo        // 输出参数
{
     UINT regSettingCount;        // 多少个寄存器
     RegSetting regSetting[MAX_REG_SETTINGS];   
} RegSettingsInfo;

 

寄存器的值和实际gain的转换关系参考:

 
LineCount = ExposureTime / Tline(行的曝光时间),而是一行要曝光多少的时间
Tline = HTS x 1/ VT_CLK
VT_CLK = VTS x HTS x FPS
Tline = 1/(VTS x FPS)

 

 
posted @ 2024-03-28 21:01  lethe1203  阅读(89)  评论(0编辑  收藏  举报