高通CamX分析---01

1. camx的入口

路径:vendor\\proprietary\camx\src\core\hal\camxhal3entry.cpp
/// Array containing hw_module_methods_t methods
static hw_module_methods_t g_hwModuleMethods =
{
    CamX::open
};
 
/// Array containing camera3_device_ops_t methods
#if defined (_LINUX)
static camera3_device_ops_t g_camera3DeviceOps =
{
    .initialize                         = CamX::initialize,
    .configure_streams                  = CamX::configure_streams,
    .construct_default_request_settings = CamX::construct_default_request_settings,
    .process_capture_request            = CamX::process_capture_request,
    .dump                               = CamX::dump,
    .flush                              = CamX::flush,
};
#else // _LINUX
static camera3_device_ops_t g_camera3DeviceOps =
{
    CamX::initialize,
    CamX::configure_streams,
    NULL,
    CamX::construct_default_request_settings,
    CamX::process_capture_request,
    NULL,
    CamX::dump,
    CamX::flush,
    NULL,
    {0},
};
#endif // _LINUX
 
/// Array of HwDeviceCloseOps to hold the close method
static HwDeviceCloseOps g_hwDeviceCloseOps =
{
    close
};

初始化流程后续再分析。。。。。

2. 硬件初始化 HwEnvironment()

路径:vendor\proprietary\camx\src\core\camxhwenvironment.cpp

HwEnvironment::HwEnvironment()
    : m_initCapsStatus(InitCapsInvalid)
    , m_pNCSObject(NULL)
{
    Initialize();
}
CamxResult HwEnvironment::Initialize()
{
	//省略代码
	result = CSLInitialize(&params); //camera service layer相机服务层初始化
   if (CamxResultSuccess == result) {
          result = QueryHwContextStaticEntryMethods(); // Query the camera platform
    }
    CAMX_ASSERT(NULL != pExternalComponent);
    if ((CamxResultSuccess == result) && (NULL != pExternalComponent)) {
        //大概连接chi部分,打开库资源
        result = ProbeChiComponents(pExternalComponent, &m_numExternalComponent); 
    }
    if (CamxResultSuccess == result) {
        // Load the OEM sensor capacity customization functions
        CAMXCustomizeCAMXInterface camxInterface;
        camxInterface.pGetHWEnvironment = HwEnvironment::GetInstance; //接口指针复制,后面调用.
        CAMXCustomizeEntry(&m_pOEMInterface, &camxInterface);
    }
     m_initCapsStatus = InitCapsInitialize; //在HwEnvironment::GetInstance中会调用到.
    }
    return result;
}
//硬件环境初始化之后,获取实例,具体怎么调到暂时不清楚
HwEnvironment* HwEnvironment::GetInstance()
{
    static HwEnvironment s_HwEnvironmentSingleton;
    /// @todo (CAMX-2684) Workaround a chicken-and-egg problem in HwEnvironment initialization...clean up later
    // By calling InitCaps here, the call it triggers back into GetInstance will not cause HwEnvironment to be recreated.
    // Branch prediction should make this essentially free
    if (InitCapsInitialize == s_HwEnvironmentSingleton.m_initCapsStatus){
        s_HwEnvironmentSingleton.InitCaps();
    }
    return &s_HwEnvironmentSingleton;
}

VOID HwEnvironment::InitCaps()
{

   EnumerateDevices();
   //https://blog.csdn.net/weixin_43381364/article/details/128178765   XML文件解析
   ProbeImageSensorModules();//解析XML文件数据,详细内容见 《3. XML文件解析》
   EnumerateSensorDevices();
   InitializeSensorSubModules(); //初始化sensor/actuator/ois/eeprom/flash数据,详细内容《4. 初始化sensor模块》
   InitializeSensorStaticCaps();

        result = m_staticEntryMethods.GetStaticCaps(&m_platformCaps[0]);
        // copy the static capacity to remaining sensor's
        for (UINT index = 1; index < m_numberSensors; index++)
        {
            Utils::Memcpy(&m_platformCaps[index], &m_platformCaps[0], sizeof(m_platformCaps[0]));
        }
        if (NULL != m_pOEMInterface->pInitializeExtendedPlatformStaticCaps)
        {
            m_pOEMInterface->pInitializeExtendedPlatformStaticCaps(&m_platformCaps[0], m_numberSensors);
        }

    if (CamxResultSuccess == result)
    {
        InitializeHwEnvironmentStaticCaps();
    }
}

3. XML文件解析

3.1 ProbeImageSensorModules

路径: /vendor/qcom/proprietary/camx/src/core/camxhwenvironment.cpp

VOID HwEnvironment::ProbeImageSensorModules()
{
    ImageSensorModuleDataManager*   pSensorManager = NULL;
    ImageSensorModuleDataManager::Create(&pSensorManager, this); //详细 《3.2 sensor模块创建》
    const UINT moduleCount = m_pImageSensorModuleDataManager->GetNumberOfImageSensorModuleData();

    for (UINT i = 0; i < moduleCount; i++) {
			pData->GetCameraPosition(&cameraPosition);
			pData->Probe(&detected, &deviceIndex);//加载sensor上下电信息、I2C信息、sensor库中接口
			//省略代码
			m_sensorInfoTable[m_numberSensors].deviceIndex = deviceIndex;
            m_sensorInfoTable[m_numberSensors].pData       = pData;
            //省略代码
            /// @todo (CAMX-1215) - Do not create tuning data manager for YUV sensor.
            result = CreateTuningDataManager(pData, m_numberSensors); //加载tuning 文件,并初始化tuning
	}
}

3.2 sensor模块创建

路径: camx\src\core\camximagesensormoduledatamanager.cpp

/* camx\src\core\camximagesensormoduledatamanager.cpp */
CamxResult ImageSensorModuleDataManager::Create(ImageSensorModuleDataManager** ppManager,HwEnvironment* pEnv)
{
    ImageSensorModuleDataManager* pManager = CAMX_NEW ImageSensorModuleDataManager();
    pManager->m_pEnv = pEnv;
    pManager->Initialize();
}

CamxResult ImageSensorModuleDataManager::Initialize()
{
    CamxResult result = CamxResultEFailed;
    result = CreateAllSensorModuleSetManagers(); 从eebin文件中获取数据
}
// @brief  Discover sensor module data objects from filesystem or other location
CamxResult ImageSensorModuleDataManager::CreateAllSensorModuleSetManagers()
{
 	/* 此处省略多行代码 */
	pEEBinDataObj->ReadEEBin();
	/* 此处省略多行代码 */
	fileCount = OsUtils::GetFilesFromPath(SensorModulesPath,  FILENAME_MAX, &binaryFiles[fileCountMM][0],
                                              "*",  "sensormodule", "*", "*", "bin");
	for (UINT i = 0; i < fileCount; i++) {
		GetSensorModuleManagerObj(&binaryFiles[i][0], &pSensorModuleSetManager); //打开二进制文件并返回sensormanger的对象
	}
}

/// @brief Opens the binary and returns the object of SensorManager
CamxResult ImageSensorModuleDataManager::GetSensorModuleManagerObj(const CHAR*   pBinName,
    													ImageSensorModuleSetManager** ppSensorModuleSetManager)
{
    pFile = OsUtils::FOpen(pBinName, "rb");
	UINT64 fileSizeBytes = OsUtils::GetFileSize(pBinName);
	/* 此处省略多行代码 */
	pSensorModuleSetManager->LoadBinaryParameters(pBuffer, fileSizeBytes); //主要是加载XML文件中数据
	/* 此处省略多行代码 */
	OsUtils::FClose(pFile);
	/* 此处省略多行代码 */
	*ppSensorModuleSetManager = pSensorModuleSetManager;
    return result;
}

3.2.1 加载XML中数据

解析XML部分简单说明:

路径: out/target/<product>/gen/STATIC_LIBERARIES/libcamxgenerated_intermediates/generated/中主要是包含了:

  1. g_chromatix : tuning 相关xml的解析code g_facedetection :人脸检测相关xml的解析code
  2. g_parser :主要的解析manager 流程图中的 imageSensorModuleDataManager 的 初始化调到了,此目录下的paramtersetmanager.cpp 的 LoadBinaryParameters(),再根据type不同进行各个sub module xml 的读取。
  3. g_sensor:camera sensor xml 解析code,包括:actuator, eeprom, flash, moduleconfig, ois ,sensor, sensormodule, eebin主要看此目录下的 camxsenordriver.cpp ,主要功能把 sensor driver xml 的各个节点内容全都 load 一遍

路径: out/target/<product>/gen/STATIC_LIBERARIES/libcamxgenerated_intermediates/generated/g_parser\
文件: parametersetmanager.cpp

/// @brief Loads binary parameters from a buffer
BOOL ParameterSetManager::LoadBinaryParameters(UINT8* buffer, UINT64 length)
{
    if (ReadHeader(buffer, length, &pos, &offset, &count, &alignment)) {
        pos   = (INT32)offset;
        Valid = ReadSections(buffer, length, &pos, count, this, alignment);
        //---------------------------------------------------------------------------
        		/// @brief Reads and validates the the binary parameter file section table
				---ParameterSetManager::ReadSections{
						AddModule(CreateModule(symbolTable.GetModule(i), alignment))
					}
					//-----------------------------------------------
							/// @brief Creates a new parameter module from a symbol table entry
							ParameterModule* ParameterSetManager::CreateModule {
								//根据不同的类型进入不同的module进行parse,相面有详细解释
								const ParameterModule* module = GetDefaultModule(entry->Type); 
								module->Parse(entry, alignment); 
							}
					//-----------------------------------------------
		//---------------------------------------------------------------------------
    }
    return Valid;
}

3.2.2 根据不同的entry->Type进入不同的module进行解析

如何进入各个模块的公共文件:下面以解析actuator为例,其他sensor(OIS/senose/ois)逻辑类似

路径: \libcamxgenerated_intermediates\generated\g_sensor\
文件: imagesensormodulesetmanager.h

class ImageSensorModuleSetManager : public ParameterSetManager
{
public:
	//省略多行代码
protected:
    virtual const ParameterModule* GetDefaultModule(
        char* type)
    {
        const ParameterModule* module = (const ParameterModule*)m_moduleMap[type]; //列表中找到对应module
        return module;
    }
    const ParameterModule* m_defaultModules[IMAGESENSORMODULE_DEFAULT_MODULE_COUNT];
    std::unordered_map<std::string, void*> m_moduleMap;
};

列表中找到对应的module
路径: \libcamxgenerated_intermediates\generated\g_sensor\
文件: imagesensormodulesetmanager.cpp

ImageSensorModuleSetManager::ImageSensorModuleSetManager()
{
    UINT32 index = 0;
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::ActuatorDriverDataClass("actuatorDriver");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::ActuatorDriverDataClass("actuatorDriver1");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::SensorDriverDataClass("sensorDriverData");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::PDAFConfigurationDataClass("PDConfigData");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::EEPROMDriverDataClass("EEPROMDriverData");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::CameraModuleDataClass("cameraModuleData");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::OISDriverDataClass("OISDriver");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::EEbinDriverClass("EEbinDriver");
    m_defaultModules[index++] = (const ParameterModule*)PARAMETER_NEW CamX::FlashDriverDataClass("flashDriverData");

    for (UINT32 i = 0; i < index; i++)
    {
        m_moduleMap[m_defaultModules[i]->Type] = (void*)m_defaultModules[i];
    }
};

3.2.3 解析actuator XML数据

路径: \libcamxgenerated_intermediates\generated\g_sensor\
文件: camxactuatordriver.cpp

ParameterModule* ActuatorDriverDataClass::Parse( ParameterFileSymbolTableEntry* entry, UINT64 alignment) const
{
    ActuatorDriverDataClass* cls = NULL;
    if (PARAMETER_STRCMP(Type, entry->Type) == 0 && Version.Value == entry->Version.Value) {
        cls = PARAMETER_NEW ActuatorDriverDataClass(GetName(entry->Type),
            entry->ModeId, entry->Mode);
        if (cls != NULL)  {
            BOOL result = TRUE;
            cls->SymbolTableID = entry->ID;
            cls->ID            = entry->ID;
            LoadActuatorDriverData(entry, cls, alignment); //加载actuator XML数据
        }
    }
    return (ParameterModule*)cls;
}

/// Load ActuatorDriverData
BOOL ActuatorDriverDataClass::LoadActuatorDriverData(ParameterFileSymbolTableEntry* entry, 
											ActuatorDriverData* structure, UINT64 alignment)
{
    Loadmodule_versionStruct(entry, &structure->module_version, alignment); //读取module_version
    LoadActuatorSlaveInfo(entry, &structure->slaveInfo, alignment); //读取slaveinfo
    LoadActuatorRegConfig(entry, &structure->registerConfig, alignment);//读取registerConfig
    camxsensorcommonClass::LoadSettingsInfo(entry, &structure->initSettings, alignment); //读取initSettings

    // Reading Optional parameter deInitSettings from symbol table
    {
        result = result && entry->Read(&structure->deInitSettingsExists, alignment);
        structure->deInitSettingsID = entry->ID;
        ParameterFileSymbolTableEntry* pointerEntry = entry->Table->ReadPointerEntry(entry, alignment);
        result = result && pointerEntry != NULL;
        if (result && structure->deInitSettingsExists)
        {
           camxsensorcommonClass::LoadSettingsInfo(pointerEntry, &structure->deInitSettings, alignment);
        } else {
            PARAMETER_INITIALIZE(structure->deInitSettings);
        }
    }
    result = result && LoadActuatorTunedParams(entry, &structure->tunedParams, alignment); //读取tunedParams

    return result;
}

3.2.4 解析ois XML数据

与解析Actuator XML文具思路相同,在此不做详细描述

路径: \libcamxgenerated_intermediates\generated\g_sensor\
文件: camxoisdriver.cpp

3.2.5 解析sensor XML数据

与解析Actuator XML文具思路相同,在此不做详细描述

路径: \libcamxgenerated_intermediates\generated\g_sensor\
文件: camxsensordriver.cpp

4. 初始化sensor模块(senosr/actuator/ois/eeprom/flash)

InitializeSensorSubModules在vendor\proprietary\camx\src\core\camxhwenvironment.cpp中的initcaps接口被调用

4.1 InitializeSensorSubModules

路径: /vendor/qcom/proprietary/camx/src/core/camxhwenvironment.cpp
功能: 初始化sensor/actuator/ois/eeprom/flash数据

VOID HwEnvironment::InitializeSensorSubModules()
{
    for (index = 0; index < m_numberSensors ; index++) {
        CAMX_LOG_VERBOSE(CamxLogGroupHWL, "Create Sensor sub modules for sensor index %d", index);
        /* m_sensorInfoTable[index]:检测到的图像传感器列表 */
        m_sensorInfoTable[index].pData->CreateSensorSubModules(&m_sensorInfoTable[index],
        																&m_cslDeviceTable[0]);
    }
}

VOID ImageSensorModuleData::CreateSensorSubModules( HwSensorInfo*  pSensorInfoTable,
    const HwDeviceTypeInfo* pCSLDeviceTable)
{
	if (CamxResultSuccess == GetCameraId(&cameraId)) //从数据表中获取cameraId
    {
    	//从解析的eeprom xml数据中获取数据
		CreateAndReadEEPROMData(pSensorInfoTable, &pCSLDeviceTable[CSLDeviceTypeEEPROM], 0);
		pActuatorDriverData  = ImageSensorModuleData::GetActuatorDriverDataObj(); //获取第一actuator数据对象
		pActuatorDriverData1 = ImageSensorModuleData::GetActuatorDriverDataObj1();//获取第二actuator数据对象
		if ((NULL != pActuatorDriverData) && (NULL != pActuatorDriverData1))
        {
        	//如果actuator xml中配置了actuatorID,判断是否与OTP中的actuatorID一致
            if ((TRUE == pActuatorDriverData1->slaveInfo.actuatorIDExists) &&
                (pActuatorDriverData1->slaveInfo.actuatorID == pSensorInfoTable->moduleCaps.OTPData.AFCalibration.actuatorID))
            {
            	//如果一致说明OTP里面使用第二actuator数据对象
                pActuatorDriverData = pActuatorDriverData1;
                CAMX_LOG_INFO(CamxLogGroupSensor,
                              "Multiple actuators found on camera %d and selected second actuator with ID: %d",
                              cameraId,
                              pActuatorDriverData1->slaveInfo.actuatorID);
            }
            m_pActuatorData = CAMX_NEW ActuatorData(pActuatorDriverData);
            //初始化actuator对焦的映射表,重点!!!!!详细描述在下面4.1.1
			m_pActuatorData->InitializeStepTable(&(pSensorInfoTable->moduleCaps.OTPData.AFCalibration));
			//获取actuator i2c频率
			if (GetOverrideI2CFrequencyMode()){
                    pActuatorDriverData->slaveInfo.i2cFrequencyMode = m_pCameraModuleData->moduleGroup
                                                  .moduleConfiguration[m_usedModuleId].i2cFrequencyMode;
                }
        }
        //获取ois数据
        pOISDriverData = ImageSensorModuleData::GetOisDriverDataObj();
        m_pOISData = CAMX_NEW OISData(pOISDriverData);
        //获取ois i2c频率
        if (GetOverrideI2CFrequencyMode()){
              pOISDriverData->slaveInfo.i2cFrequencyMode = m_pCameraModuleData->moduleGroup
                                               .moduleConfiguration[m_usedModuleId].i2cFrequencyMode;
        }
        //获取eeprom xml中数据
        pFlashDriverData  = ImageSensorModuleData::GetFlashDriverDataObj();
        m_pFlashData = CAMX_NEW FlashData(pFlashDriverData, pSensorInfoTable, &pCSLDeviceTable[CSLDeviceTypeFlash]);
        if (GetOverrideI2CFrequencyMode()) {
               pFlashDriverData->i2cInfo.i2cFrequencyMode = m_pCameraModuleData->moduleGroup
                                            .moduleConfiguration[m_usedModuleId].i2cFrequencyMode;
        }
	}
}

4.1.1 InitializeStepTable 初始化AF对焦映射表

路径: /vendor/qcom/proprietary/camx/src/core/camxactuatordata.cpp

CamxResult ActuatorData::InitializeStepTable(
    AFCalibrationData* pAFData) //pAFData是从OTP中获取的actuator校准数据
{
    CamxResult                result        = CamxResultEOutOfBounds;
    UINT                      regionSize    = m_pActuatorDriverData->tunedParams.regionParams.regionCount;
    ActuatorRegionParams*     pRegionParams = m_pActuatorDriverData->tunedParams.regionParams.region;

    if ((NULL != pAFData) && (TRUE == pAFData->isAvailable)) {
    	//模组出厂时会有实际有效行程、校准值等数据,需要对配置的XML数据进行校准
        result = CalibrateActuatorDriverData(pAFData); //详细4.1.2,主要校准codestep、initialCode
    } else {
        // Step table can be initialized even without AF calibration data
        CAMX_LOG_INFO(CamxLogGroupSensor, "AF calibration data is not available in OTP data, pAFData: %p", pAFData);
    }
	//定义对焦映射表数组的长度
    m_stepTableSize = pRegionParams[regionSize - 1].macroStepBoundary; //XML中数据macroStepBoundary
    if (m_stepTableSize <= MaxSteps) //MaxSteps默认定义400,注意XML定义是否超过该值,camxactuatordata.h
    {
        UINT  stepIndex   = 0;
        UINT  j           = 0;
        FLOAT currentCode = m_pActuatorDriverData->tunedParams.initialCode;

        for (UINT i = 0; i < regionSize; i++)
        {
            if (i > 0)
            {
                CAMX_ASSERT_MESSAGE(pRegionParams[i].macroStepBoundary > pRegionParams[i-1].macroStepBoundary,
                                    "Step Boundary check failed for index: %d, step boundary: %d, previous step boundary: %d",
                                    i, pRegionParams[i].macroStepBoundary, pRegionParams[i - 1].macroStepBoundary);
            }

            for (;(stepIndex < pRegionParams[i].macroStepBoundary); stepIndex++)
            {
                // infinity position stored at largest index to match AF algorithm definition
                j              = m_stepTableSize - 1 - stepIndex;
                CAMX_ASSERT(j < MaxSteps);
              //currentCode和codePerStep都是float型,累加强转为INT16,所以映射表值间隔并不是完全等于codeperstep
                m_stepTable[j] = static_cast<INT16>(currentCode);
                currentCode   += pRegionParams[i].codePerStep;

                CAMX_LOG_VERBOSE(CamxLogGroupSensor, "Table[%d] %d", j, m_stepTable[j]);
            }
        }

        CAMX_ASSERT_MESSAGE(stepIndex == m_stepTableSize, "Step index: %d, table size: %d", stepIndex, m_stepTableSize);
        m_infinityDAC = m_pActuatorDriverData->tunedParams.initialCode;
        m_macroDAC    = m_stepTable[j]; //映射表最后一个值等于近焦值
        result        = CamxResultSuccess;

		//numberOfDistances是OTP数据,比如某个10bit位宽IC的OTP数据如下:
		// Lens Calibration Data: numberOfDistances:5
		// Distance(CM) = 500 : DAC = 285
		// Distance(CM) = 35 : DAC = 325
		// Distance(CM) = 15 : DAC = 366
		// Distance(CM) = 6 : DAC = 506
		// Distance(CM) = 2 : DAC = 829
        if ((NULL != pAFData) && (0 != pAFData->numberOfDistances))
        {
            BOOL   isAscending  = (m_stepTable[0] < m_stepTable[m_stepTableSize - 1]) ? TRUE : FALSE;
            UINT   stepPosition = 0;
            FLOAT  factor       = 1;

            if (0 != pRegionParams[0].codePerStep)
            {
                factor = (1 / pRegionParams[0].codePerStep);
            }

            for (UINT i = 0; i < pAFData->numberOfDistances ; i++)
            {
                INT16 DAC = pAFData->calibrationInfo[i].DACValue;

                stepPosition = Utils::FindClosestInSortedIntArray(m_stepTable, m_stepTableSize, DAC);
                if (TRUE == isAscending)
                {
                    if (pAFData->calibrationInfo[i].DACValue < m_stepTable[stepPosition])
                    {
                        pAFData->calibrationInfo[i].stepPosition =
                            (stepPosition) - ((abs(m_stepTable[stepPosition]) - abs(DAC)) * (abs(factor)));
                    }
                    else
                    {
                        pAFData->calibrationInfo[i].stepPosition =
                            (stepPosition) + ((abs(DAC) - abs(m_stepTable[stepPosition])) * (abs(factor)));
                    }
                }
                else
                {
                    if (pAFData->calibrationInfo[i].DACValue < m_stepTable[stepPosition])
                    {
                        pAFData->calibrationInfo[i].stepPosition =
                            (stepPosition) + ((abs(m_stepTable[stepPosition]) - abs(DAC)) * (abs(factor)));
                    }
                    else
                    {
                        pAFData->calibrationInfo[i].stepPosition =
                            stepPosition - ((abs(DAC) - abs(m_stepTable[stepPosition])) * (abs(factor)));
                    }
                }
                CAMX_LOG_VERBOSE(CamxLogGroupSensor,
                               "calibration Distance: %d, DAC: %d, stepPosition: %f",
                               pAFData->calibrationInfo[i].chartDistanceCM,
                               pAFData->calibrationInfo[i].DACValue,
                               pAFData->calibrationInfo[i].stepPosition);
            }
        }
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupSensor, "Failed to initilize step table");
    }

    return result;
}

4.1.2 CalibrateActuatorDriverData 校准AF初始化映射表对焦值

路径: /vendor/qcom/proprietary/camx/src/core/camxactuatordata.cpp

CamxResult ActuatorData::CalibrateActuatorDriverData(const AFCalibrationData* pAFData)
{
    CamxResult              result          = CamxResultSuccess;
    UINT32                  regionSize      = m_pActuatorDriverData->tunedParams.regionParams.regionCount;
    ActuatorRegionParams*   pRegionParams   = m_pActuatorDriverData->tunedParams.regionParams.region;
    UINT32                  stepTableSize   = pRegionParams[regionSize - 1].macroStepBoundary;
    INT32                   DACRange        = 0;
    FLOAT                   codePerStep     = 0;
    INT32                   signSpecifier   = 1;
    INT16                   infinityDAC     = 0;
    INT16                   macroDAC        = 0;
    UINT16                  dataBitWidth    = m_pActuatorDriverData->slaveInfo.dataBitWidth;
    ActuatorType            actuatorType    = m_pActuatorDriverData->slaveInfo.actuatorType;
    INT16                   lowerBound      = 0;
    INT16                   upperBound      = 0;

    if (ActuatorType::VCM == actuatorType) {
        lowerBound = 0; //作为底值IC处理
        //数据的理论边界值,如果dataBitWidth=10,返回2的10次方,范围0~1023
        upperBound = static_cast<INT16>(Utils::Power(2.0, dataBitWidth) - 1);
    } else if (ActuatorType::BIVCM == actuatorType) {
    	//数据的理论边界值,如果dataBitWidth=10,范围-512~511
        lowerBound  = static_cast<INT16>(-Utils::Power(2.0, dataBitWidth-1));
        upperBound  = static_cast<INT16>(Utils::Power(2.0, dataBitWidth-1) - 1);
    }

    infinityDAC     = pAFData->infinityDAC; //OTP中的远焦极限DAC值
    macroDAC        = pAFData->macroDAC; //OTP中的近焦极限DAC值
    DACRange        = macroDAC - infinityDAC; //DAC的有效范围
    signSpecifier   = (infinityDAC > 0) ? (1) : (-1);
    infinityDAC    += static_cast<INT16>(pAFData->infinityMargin * Utils::AbsoluteINT32(DACRange) * signSpecifier);

    signSpecifier   = (macroDAC > 0) ? (1) : (-1);
    macroDAC       += static_cast<INT16>(pAFData->macroMargin * Utils::AbsoluteINT32(DACRange) * signSpecifier);

    if ((ActuatorType::VCM == actuatorType) || (ActuatorType::BIVCM == actuatorType))
    {
    	//取较小的范围,确保行程安全
        macroDAC    = (macroDAC > upperBound) ? (upperBound) : (macroDAC);//在DAC范围和OTP数据范围中取较小值
        infinityDAC = (infinityDAC < lowerBound) ? (lowerBound) : (infinityDAC);//在DAC范围和OTP数据范围中取较大值
    }

    DACRange    = (macroDAC) - (infinityDAC);
    //校准累加步长
    codePerStep = (DACRange / static_cast<FLOAT>(stepTableSize)); //stepTableSize:XML中参数macroStepBoundary

    for (UINT size = 0; size < regionSize; size++) {
        pRegionParams[size].codePerStep = codePerStep; //校准后的step传出去
    }

    for (UINT size = 0; size < m_pActuatorDriverData->initSettings.regSettingCount; size++) {
        if (pAFData->hallRegisterAddr == m_pActuatorDriverData->initSettings.regSetting[size].registerAddr)
        {
            m_pActuatorDriverData->initSettings.regSetting[size].registerData[0] = pAFData->hallOffsetBias;
        }
    }
	//校准后的远焦值作为初始化code,然后累加codePerStep
    m_pActuatorDriverData->tunedParams.initialCode = infinityDAC;

    return result;
}

5. InitializeSensorStaticCaps

暂无分析。。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值