Camera Sensor介面配置

lethe1203發表於2024-03-28
參考資料:極客筆記
以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)

相關文章