文章目录
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(¶ms); //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/
中主要是包含了:
g_chromatix
: tuning 相关xml的解析code g_facedetection :人脸检测相关xml的解析codeg_parser
:主要的解析manager 流程图中的 imageSensorModuleDataManager 的 初始化调到了,此目录下的paramtersetmanager.cpp 的 LoadBinaryParameters(),再根据type不同进行各个sub module xml 的读取。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
暂无分析。。。。