streammanager 初始化流程
目录
STRM_Initialize
Gptp::Init
Config::Init
SensorManager::Init
SensorPlatform::SensorPlatformInit
SensorManager::LoadSensorLib
SensorManager::OpenSensorLib
SensorManager::DetectAll
SensorManager::DetectHandlerThread
SensorManager::ProcessDetectEvent
/**
* STRM_Initialize
*
* @brief Initialize stream manager
* @param initialization parameters
*
* @return CAMERA_SUCCESS if successful;
*/
CamStatus_e STRM_Initialize(const QCarCamInit_t* pInitParams)
{
QCX_LOG(STREAM_MGR, HIGH, "API: %s", __FUNCTION__);
CamStatus_e result = CAMERA_EFAILED;
StreamManager* pStrmManager = NULL;
if (NULL == pInitParams)
{
QCX_LOG(STREAM_MGR, ERROR, "Null pointer passed.");
result = CAMERA_EBADPARAM;
}
else
{
/* Create Stream manager instance. */
pStrmManager = StreamManager::GetInstance();
if (NULL == pStrmManager)
{
QCX_LOG(STREAM_MGR, ERROR, "Stream Manager instance creation failed.");
result = CAMERA_ENOMEMORY;
}
else
{
result = CAMERA_SUCCESS;
}
}
if (CAMERA_SUCCESS == result)
{
QCX_LOG(STREAM_MGR, HIGH, "%s called with init params (flags=%#x, apiVersion=%u)", __FUNCTION__, pInitParams->flags, pInitParams->flags);
result = pStrmManager->Initialize(pInitParams);
if (CAMERA_SUCCESS == result)
{
QCX_LOG(STREAM_MGR, DEBUG, "Stream Manager initialization success.");
}
/* No need to destroy stream manager instance on failure. */
}
return result;
}
//解析xml errInjen 配置进行debug log 输出
初始化解串器配置/cameraconfigsa8650.c配置的信息
/**
* @brief
* Function used to initialize.
*
* @param pInitParams [in]
* pointer to init params
*
* @return
* Status as defined in CamStatus_e
*/
CamStatus_e StreamManager::Initialize(const QCarCamInit_t* pInitParams)
{
CamStatus_e result = CAMERA_SUCCESS;
CAM_TRACE_LOG(STREAM_MGR, "StreamManager::Initialize");
/* Check API version */
if (pInitParams->apiVersion >= QCARCAM_VERSION_MINIMUM_COMPATIBLE)
{
QCX_LOG(STREAM_MGR, ERROR, "API version %#x is not supported",
pInitParams->apiVersion);
result = CAMERA_ENOTSUPPORTED;
}
else
{
/* Initialize GPTP
*
* GPTP service might not be available at this time and hence this
* call might fail.
* TODO. Need to try initializing at a later time.
*
* We are not checking the error code here, since it is not a fatal error,
* and we already have the error prints from inside the method */
Gptp::GetInstance()->Init();
/* Initalize dynamic configuration */
//解析xml errInjen 配置进行debug log 输出
//errInjen未配置在xml中
Config::GetInstance()->Init();
/* TODO: Need to move it to SI_Init */
//初始化解串器配置/cameraconfigsa8650.c配置的信息
result = SensorManager::GetInstance()->Init();
if (CAMERA_SUCCESS != result)
{
QCX_LOG(STREAM_MGR, ERROR, "Failed in sensor manager init");
}
else
{
result = SensorManager::GetInstance()->DetectAll();
if (CAMERA_SUCCESS != result)
{
QCX_LOG(STREAM_MGR, ERROR, "Failed in sensor detection");
}
else
{
QCX_LOG(STREAM_MGR, HIGH, "Sensor Manager Init and DetectAll successful");
/* TODO: Need to add init call for CSL */
result = CAMXHAL::GetInstance()->Init();
if (CAMERA_SUCCESS != result)
{
QCX_LOG(STREAM_MGR, ERROR, "CAMX HAL Init failed");
}
else
{
result = CAMXHAL::GetInstance()->InitializeMetatable(&g_QccMetadataTable, g_metadataTableElemCount);
if (CAMERA_SUCCESS != result)
{
m_QccMetadatatable_init = false;
QCX_LOG(STREAM_MGR, ERROR, "Initalizing metadata cached table failed(result = %d)", result);
}
else
{
m_QccMetadatatable_init = true;
QCX_LOG(STREAM_MGR, DEBUG, "Initalizing metadata cached table successed");
}
}
}
}
/*Create the Lock for Global list of input Ids*/
result = OSAL_CriticalSectionCreate(&m_OpenInputIdslock);
if (CAMERA_SUCCESS != result)
{
QCX_LOG(STREAM_MGR, ERROR, "OSAL_CriticalSectionCreate failed, result = %d", result);
}
}
CAM_TRACE_LOG(STREAM_MGR, "StreamManager::Initialize : End");
return result;
}
/**
* @brief
* Get singleton instance of gptp.
*/
Gptp* Gptp::GetInstance()
{
static Gptp s_GptpSingleton;
return &s_GptpSingleton;
}
//获取GPTP_ENABLE_KEY的value
//GPTP_ENABLE_KEY未进行配置不会初始化gptpInit
/**
* @brief
* Initialize GPTP.
*
* @return
* Status as defined in CamStatus_e
*/
CamStatus_e Gptp::Init(void)
{
CamStatus_e result = CAMERA_EFAILED;
CamStatus_e resultTemp = CAMERA_EFAILED;
//获取GPTP_ENABLE_KEY的value
resultTemp = Config::GetInstance()->GetGptpEnableFromConfig(&mGptpEnable);
if(CAMERA_SUCCESS != resultTemp)
{
QCX_LOG(STREAM_MGR, ERROR, "Failed to read GPTP Enable from config. Disabling GPTP");
mGptpEnable = GPTP_DISABLED;
}
//GPTP_ENABLE_KEY未进行配置不会初始化gptpInit
if(GPTP_ENABLED == mGptpEnable){
bool state;
state = gptpInit();
if (true != state)
{
QCX_LOG(STREAM_MGR, ERROR, "gptp init failed");
}
else
{
QCX_LOG(STREAM_MGR, DEBUG, "gptp init success");
result = CAMERA_SUCCESS;
}
}
return result;
}
/**
* @brief
* Read GPTP enable value from config.
*
* @param gptpEn [out]
* pointer to the gptp enable flag.
*
* @return
* Status as defined in CamStatus_e.
*/
CamStatus_e Config::GetGptpEnableFromConfig(uint32_t *pGptpEn)
{
CamStatus_e rc = CAMERA_EFAILED;
rc = GetValFromConfigOverrideSetting(GPTP_ENABLE_KEY, pGptpEn);
if (CAMERA_SUCCESS != rc)
{
QCX_LOG(STREAM_MGR, HIGH, "GPTP Enable config read failed");
}
else
{
QCX_LOG(STREAM_MGR, LOW, "Config read success: GptpEn = %u", *pGptpEn);
}
return rc;
}
*
* @param key [in]
* key of the config.
*
* @param value [out]
* pointer to value of the config.
*
* @return
* Status as defined in CamStatus_e.
*/
CamStatus_e Config::GetValFromConfigOverrideSetting(uint32_t key, uint32_t *pValue)
{
CamStatus_e rc = CAMERA_ENOTFOUND;
const CameraConfigInfo_t* pCamConfig = nullptr;
pCamConfig = PLM_GetCameraConfig();
if (nullptr == pCamConfig)
{
QCX_LOG(STREAM_MGR, ERROR, "Failed to query cameraconfig");
}
else
{
/* Search the config for request queue depth value. */
for (uint32_t idx = 0; idx < CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES; idx++)
{
if (key == pCamConfig->settingsOverrides[idx].key)
{
*pValue = pCamConfig->settingsOverrides[idx].value;
rc = CAMERA_SUCCESS;
break;
}
}
}
return rc;
}
/**************************************************************************************************
@brief
Get camera config
@return
Error const pointer to CameraConfigInfo_t
**************************************************************************************************/
const CameraConfigInfo_t* PLM_GetCameraConfig(void)
{
if (TRUE == g_PlatformCtxt.bInitialized)
{
return g_PlatformCtxt.pCameraConfigInfo;
}
return NULL;
}
static int CameraConfigXMLParseFile(CameraConfigInfo_t *boardInfo)
{
int rc = 0;
xmlDocPtr pXmlDoc = NULL;
xmlNodePtr pCur = NULL;
const char* filename = CAMERA_CONFIG_XML_FILE;
uint32_t settingsOverrideIdx = 0;
CAM_MSG(HIGH, "CameraConfig xml file name:%s", filename);
if(access(filename, F_OK))
{
CAM_MSG(HIGH, "CameraConfig file not available. Will use defaults");
rc = -1;
}
if (!rc)
{
pXmlDoc = xmlParseFile(filename);
if (pXmlDoc == NULL)
{
CAM_MSG(ERROR, "CameraConfig file not parsed successfully");
rc = -1;
}
}
if (!rc)
{
pCur = xmlDocGetRootElement(pXmlDoc);
if (pCur == NULL)
{
CAM_MSG(ERROR, "Empty CameraConfig file");
xmlFreeDoc(pXmlDoc);
rc = -1;
}
}
if (!rc)
{
if (xmlStrcmp(pCur->name, (const xmlChar *) "CameraConfig"))
{
CAM_MSG(ERROR, "Wrong CameraConfig file format, root node != CameraConfig");
xmlFreeDoc(pXmlDoc);
rc = -1;
}
else
{
pCur = pCur->xmlChildrenNode;
}
}
//Parse the file
while(pCur != NULL && !rc)
{
if (!(xmlStrcmp(pCur->name, (const xmlChar *) "board")))
{
XML_GET_INT_ATTR(boardInfo->socId, pCur, "socId", 1, uint32_t);
XML_GET_STRING_ATTR(boardInfo->boardName, pCur, "name", 1);
xmlNodePtr pChild = pCur->xmlChildrenNode;
while(pChild != NULL && !rc)
{
if(!(xmlStrcmp(pChild->name, (const xmlChar *) "i2cDevs")))
{
//配置camera sensorlib i2c设备的个数
XML_GET_INT_ATTR(boardInfo->numI2cDevices, pChild, "numI2cDevices", 1, uint32_t);
if(CAM_CFG_MAX_NUM_I2C_DEVICES <= boardInfo->numI2cDevices)
{
CAM_MSG(ERROR, "Number of I2cDevices exceeds max %d", CAM_CFG_MAX_NUM_I2C_DEVICES);
rc = -1;
break;
}
rc = CameraConfigXMLParseI2CDevs(pChild, boardInfo);
}
else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "cameraLibs")))
{
XML_GET_INT_ATTR(boardInfo->numCameraLibs, pChild, "numCameraLibs", 1, uint32_t);
if(CAM_CFG_MAX_NUM_SENSOR_LIBS <= boardInfo->numCameraLibs)
{
CAM_MSG(ERROR, "Number of CameraLibs exceeds max %d", CAM_CFG_MAX_NUM_SENSOR_LIBS);
rc = -1;
break;
}
rc = CameraConfigXMLParseSensorLibs(pChild, boardInfo);
}
else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "settingsOverrides")))
{
uint32_t key = 0;
uint32_t value = 0;
XML_GET_INT_ATTR(key, pChild, "key", 1, uint32_t);
XML_GET_INT_ATTR(value, pChild, "value", 1, uint32_t);
if (CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES <= settingsOverrideIdx)
{
CAM_MSG(ERROR, "Number of engine settings exceeds max %d", CAM_CFG_MAX_NUM_SETTINGS_OVERRIDES);
rc = -1;
break;
}
//获取xml中配置的settingsOverrrides
boardInfo->settingsOverrides[settingsOverrideIdx].key = key;
boardInfo->settingsOverrides[settingsOverrideIdx].value = value;
settingsOverrideIdx++;
}
pChild = pChild->next;
}
}
else if(!(xmlStrcmp(pCur->name, (const xmlChar *) "inputMapping")))
{
XML_GET_INT_ATTR(boardInfo->numInputs, pCur, "numInputs", 1, uint32_t);
//获取xml的input信息
rc = CameraConfigXMLParseInputMapping(pCur, boardInfo);
}
pCur = pCur->next;
}
xmlFreeDoc(pXmlDoc);
return rc;
}
static int CameraConfigXMLParseInputMapping(xmlNodePtr pParent, CameraConfigInfo_t *boardInfo)
{
int rc = 0;
xmlNodePtr pCur = pParent->xmlChildrenNode;
uint32_t srcIdx = 0;
while (pCur != NULL && !rc)
{
if (!(xmlStrcmp(pCur->name, (const xmlChar *) "inputMap")))
{
xmlNodePtr pChild;
if(CAM_CFG_MAX_NUM_INPUT_MAPPING <= srcIdx)
{
CAM_MSG(ERROR, "Number of input mapping exceeds max %d", CAM_CFG_MAX_NUM_INPUT_MAPPING);
rc = -1;
break;
}
XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].qcarcamId, pCur, "qcarcamId", 1, uint32_t);
XML_GET_STRING_ATTR(boardInfo->inputs[srcIdx].name, pCur, "name", 1);
pChild = pCur->xmlChildrenNode;
pChild = pChild->next;
if(!(xmlStrcmp(pChild->name, (const xmlChar *) "inputSrc")))
{
XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].sensorLibId, pChild, "sensorLibId", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].devId, pChild, "devId", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->inputs[srcIdx].subdevId, pChild, "subdevId", 1, uint32_t);
}
srcIdx++;
}
pCur = pCur->next;
}
return rc;
}
/*
* Initialise config Class.
*
* @return
* Status as defined in CamStatus_e.
*/
void Config::Init()
{
/* TODO: Need to cleanup and implement proper init method.
* Need to initialise all the configs in the init method,
* which will be consumed by clients using getter methods.
* (Now error injection configs are only initalised here.
**/
if(CAMERA_SUCCESS != InitErrInjConfig())
{
QCX_LOG(STREAM_MGR, HIGH, "Error Injection Configs not found");
}
}
* @brief
* Read Error Injection configs from global configs and
* update corresponding config class memeber.
*
* @return
* Status as defined in CamStatus_e.
*/
CamStatus_e Config::InitErrInjConfig()
{
CamStatus_e rc = CAMERA_ENOTFOUND;
uint32_t errInj1 = 0;
uint32_t errInj2 = 0;
uint64_t config = 0;
/* Read and update the error injection configs */
m_errInjConfig.errInjEn = false;
rc = GetValFromConfigOverrideSetting(ERR_INJ_VAL1_KEY, &errInj1);
if (CAMERA_SUCCESS != rc)
{
QCX_LOG(STREAM_MGR, HIGH, "Config not present for ERR_INJ_VAL1_KEY");
}
else
{
rc = GetValFromConfigOverrideSetting(ERR_INJ_VAL2_KEY, &errInj2);
if (CAMERA_SUCCESS != rc)
{
QCX_LOG(STREAM_MGR, HIGH, "Config not present for ERR_INJ_VAL2_KEY");
}
else
{
/* Pack the two 32 bit values to form 64bit value */
config = ((uint64_t)errInj2 << 32) | errInj1;
QCX_LOG(STREAM_MGR, DEBUG, "Config read success: ErrInj Val2 = %x,"
" ErrInj Val1 = %x, config = %lx", errInj2, errInj1, config);
/*
* The 64 bit Config value is divided as
* [15:0] : 16 bits -> Request Id
* [31:16] : 16 bits -> Error Source
* [47:32] : 16 bits -> Error Code
* [59:48] : 12 bits -> Camera Id
* [63:60] : 4 bits -> Error Id
* */
m_errInjConfig.requestId = (config & 0xFFFF);
m_errInjConfig.errorSrc = ((config >> 16) & 0xFFFF);
m_errInjConfig.errorCode = ((config >> 32) & 0xFFFF);
m_errInjConfig.cameraId = ((config >> 48) & 0xFFF);
m_errInjConfig.errorId = ((config >> 60) & 0xF);
QCX_LOG(STREAM_MGR, DEBUG, " Request id = %x, Error Src = %x,"
" Error Code = %x, Camera Id = %d, Error Id = %x",
m_errInjConfig.requestId, m_errInjConfig.errorSrc,
m_errInjConfig.errorCode, m_errInjConfig.cameraId,
m_errInjConfig.errorId);
if (ERROR_CAMERA_CODE_INVALID != m_errInjConfig.errorCode)
{
QCX_LOG(STREAM_MGR, DEBUG, "Valid Error Code: Enabling Error injection");
m_errInjConfig.errInjEn = true;
rc = CAMERA_SUCCESS;
}
}
}
return rc;
}
//注册m_SensorPlatformApi函数操作接口
//获取xml中的camera 对应的解串器的i2c num配置
//创建 pDetectHndlr->detectQ
//创建pDetectHndlr->signal 信号量
//创建SensorManager::DetectHandlerThread 处理detectQ中的数据
//初始化pSensorLib 获取boardInfo->cameraLib中的SensorLibConfig
//加载sensorlib
//匹配解串器型号配置 解串器地址mode
//配置devIdx解串器信息
//配置解串器的index rang 0-3
//配置解串器numdevices id
//配置input 信息
/**
* @brief Initialize Sensor Manager
* @return #CamStatus_e
*/
CamStatus_e SensorManager::Init()
{
CamStatus_e result{CAMERA_SUCCESS};
m_pCameraConfigInfo = PLM_GetCameraConfig();
if (nullptr == m_pCameraConfigInfo)
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to query cameraconfig");
return result;
}
//注册m_SensorPlatformApi函数操作接口
m_SensorPlatformApi.I2CRead = &I2CRead;
m_SensorPlatformApi.I2CWrite = &I2CWrite;
m_SensorPlatformApi.I2CTransact = &I2CTransact;
m_SensorPlatformApi.I2CWriteSync = &I2CWriteSync;
m_SensorPlatformApi.ExecuteGpioAndPowerSequence = &ExecuteGpioAndPowerSequence;
m_SensorPlatformApi.GPIOSetValue = &GPIOSetValue;
m_SensorPlatformApi.GPIOGetValue = &GPIOGetValue;
m_SensorPlatformApi.SetupGpioInterrupt = &SetupGpioInterrupt;
m_SensorPlatformApi.StartCCIFrameSync = &StartCCIFrameSync;
m_SensorPlatformApi.StopCCIFrameSync = &StopCCIFrameSync;
//获取xml中的camera 对应的解串器的i2c num配置
m_numSensorLibs = m_pCameraConfigInfo->numCameraLibs;
char thread_name[64];
const uint64_t nMaxElementSize = sizeof(QCXInputEventMsgType);
m_detectHandlerIsExit = FALSE;
result = QCXCameraCreateSignal(&m_detectSignalDone);
if (result != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not create Signal");
}
result = OSAL_CriticalSectionCreate(&m_detectMutex);
if (result != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not create Mutex");
}
for (int i = 0; i < MAX_DETECT_THREAD_IDX; i++)
{
QCXInputDetectHandlerType* pDetectHndlr = &m_detectHandler[i];
//创建 pDetectHndlr->detectQ
result = QCXQueueCreate(nMa xElementSize, CAM_CFG_MAX_NUM_SENSOR_LIBS, FALSE, &pDetectHndlr->detectQ);
if (result != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not create Queue");
}
//创建pDetectHndlr->signal 信号量
result = QCXCameraCreateSignal(&pDetectHndlr->signal);
if (CAMERA_SUCCESS != result)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not create Signal");
}
UNUSED_VAL(snprintf(thread_name, sizeof(thread_name), "sensormgr_thrd%d", i));
if (CAMERA_SUCCESS == result)
{
//创建SensorManager::DetectHandlerThread 处理detectQ中的数据
result = OSAL_ThreadCreate(QCXThreadDefaultPriority, &SensorManager::DetectHandlerThread, pDetectHndlr,
DETECT_STACK_SIZE, thread_name, &pDetectHndlr->threadId);
if (result != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not create Thread");
}
}
}
for (uint32_t libIdx = 0U; libIdx < m_numSensorLibs; libIdx++)
{
QcxSensorLib_t* const pSensorLib = &m_sensorLibs[libIdx];
//初始化pSensorLib 获取boardInfo->cameraLib中的SensorLibConfig
pSensorLib->pSensorLibConfig = &m_pCameraConfigInfo->cameraLib[libIdx];
pSensorLib->pSensorPlatform = SensorPlatform::SensorPlatformInit(pSensorLib->pSensorLibConfig);
if (nullptr == pSensorLib->pSensorPlatform)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not load sensorplatform for lib %d",
pSensorLib->pSensorLibConfig->sensorLibId);
continue;
}
//加载sensorlib
result = LoadSensorLib(pSensorLib);
if (CAMERA_SUCCESS != result)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not load sensor lib %d",
pSensorLib->pSensorLibConfig->sensorLibId);
continue;
}
QCX_LOG(SENSOR_MGR, HIGH, "Open sensor lib %d ...",
pSensorLib->pSensorLibConfig->sensorLibId);
//匹配解串器型号配置 解串器地址mode
result = OpenSensorLib(pSensorLib);
if (CAMERA_SUCCESS != result)
{
QCX_LOG(SENSOR_MGR, ERROR, "Could not open sensor lib %d",
pSensorLib->pSensorLibConfig->sensorLibId);
continue;
}
pSensorLib->m_nInputDevices = pSensorLib->pSensorLibConfig->numDevices;
//配置devIdx解串器信息
// Search list of sensor device drivers to determine which ones are
// actually available for use
for (uint32_t devIdx = 0U; devIdx < pSensorLib->m_nInputDevices; devIdx++)
{
QcxInputDevice_t* const pInputDev = &pSensorLib->m_InputDevices[devIdx];
pInputDev->delaySuspendFlag = FALSE;
//配置解串器的index rang 0-3
pInputDev->sensorlibId = libIdx;
//配置解串器numdevices id
pInputDev->devId = devIdx;
pInputDev->pDeviceConfig = &pSensorLib->pSensorLibConfig->devices[devIdx];
}
}
//配置input 信息
for (uint32_t inputmapIdx = 0U; inputmapIdx < m_pCameraConfigInfo->numInputs; inputmapIdx++)
{
QcxInputMapping_t* const pInputMap = &m_InputMappingTable[inputmapIdx];
pInputMap->pInfo = &m_pCameraConfigInfo->inputs[inputmapIdx];
pInputMap->isAvailable = FALSE;
m_nInputMapping++;
}
// return success to keep going with whatever sensor libraries were detected
return CAMERA_SUCCESS;
}
//解析xml 获取boardInfo->cameraLib中的SensorLibConfig
static int CameraConfigXMLParseSensorLibs(xmlNodePtr pParent, CameraConfigInfo_t *boardInfo)
{
int rc = 0;
uint32_t cameraLibIdx = 0;
xmlNodePtr pCur = pParent->xmlChildrenNode;
while(pCur != NULL && !rc)
{
if(!(xmlStrcmp(pCur->name, (const xmlChar *) "cameraLib")))
{
xmlNodePtr pChild;
if(cameraLibIdx >= boardInfo->numCameraLibs)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
return rc;
}
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].sensorLibId, pCur, "sensorLibId", 1, uint32_t);
pChild = pCur->xmlChildrenNode;
while(pChild != NULL && !rc)
{
if(!(xmlStrcmp(pChild->name, (const xmlChar *) "driverInfo")))
{
XML_GET_STRING_ATTR(boardInfo->cameraLib[cameraLibIdx].driverInfo.strSensorLibraryName, pChild, "strSensorLibraryName", 1);
XML_GET_STRING_ATTR(boardInfo->cameraLib[cameraLibIdx].driverInfo.strSensorLibGetInterfFcn, pChild, "strSensorLibGetInterfFcn", 1);
}
else if(!(xmlStrcmp(pChild->name, (const xmlChar *) "inputdevs")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].numDevices, pChild, "numDevices", 1, uint32_t);
uint32_t devId = 0;
xmlNodePtr pSubChild = pChild->xmlChildrenNode;
while(pSubChild != NULL && !rc)
{
if(devId >= boardInfo->cameraLib[cameraLibIdx].numDevices)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSubChild->name, (const xmlChar *) "inputdev")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceId, pSubChild, "deviceId", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceType, pSubChild, "deviceType", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceMode, pSubChild, "deviceMode", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].deviceI2cAddr, pSubChild, "deviceI2cAddr", 1, uint8_t);
xmlNodePtr pSSubChild;
pSSubChild = pSubChild->xmlChildrenNode;
while(pSSubChild != NULL && !rc)
{
if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "subdevs")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numSubdevices, pSSubChild, "numSubdevices", 1, uint8_t);
uint32_t SubDevIdx = 0;
xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;
while(pSSubChild1 != NULL && !rc)
{
if(SubDevIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numSubdevices)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "subdev")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].subdevId, pSSubChild1, "subdevId", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].type, pSSubChild1, "type", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].serAlias, pSSubChild1, "serAlias", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].snsrAlias, pSSubChild1, "snsrAlias", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].snsrModeId, pSSubChild1, "snsrModeId", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].fsyncMode, pSSubChild1, "fsyncMode", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].fsyncFreq, pSSubChild1, "fsyncFreq", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].subdevices[SubDevIdx].colorSpace, pSSubChild1, "colorSpace", 1, uint8_t);
SubDevIdx++;
}
else if(!xmlNodeIsText(pSSubChild1))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);
rc = -1;
}
pSSubChild1 = pSSubChild1->next;
}
}
else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "csiconn")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi, pSSubChild, "numCsi", 1, uint8_t);
uint32_t csiIdx = 0;
if(SENSORLIB_MAX_NUM_CSI <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi)
{
CAM_MSG(ERROR, "Number of CSI exceeds max %d", SENSORLIB_MAX_NUM_CSI);
rc =-1;
break;
}
xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;
while(pSSubChild1 != NULL && !rc)
{
if(csiIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numCsi)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "csiInfo")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].csiId, pSSubChild1, "csiId", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].numLanes, pSSubChild1, "numLanes", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].laneAssign, pSSubChild1, "laneAssign", 1, uint16_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].ifeMap, pSSubChild1, "ifeMap", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].numIfeMap, pSSubChild1, "numIfeMap", 1, uint8_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].csiInfo[csiIdx].forceHSmode, pSSubChild1, "forceHSmode", 1, uint8_t);
csiIdx++;
}
else if(!xmlNodeIsText(pSSubChild1))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);
rc = -1;
}
pSSubChild1 = pSSubChild1->next;
}
}
else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "i2cinfo")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts, pSSubChild, "numI2cPorts", 1, uint8_t);
uint32_t I2cIdx = 0;
if(SENSORLIB_MAX_NUM_I2C_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts)
{
CAM_MSG(ERROR, "Number of I2c ports exceeds max %d", SENSORLIB_MAX_NUM_I2C_PER_DEVICE);
rc =-1;
break;
}
xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;
while(pSSubChild1 != NULL && !rc)
{
if(I2cIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numI2cPorts)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "i2cPort")))
{
boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].i2ctype = CameraConfigXMLParseI2cType(pSSubChild1);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].deviceId, pSSubChild1, "deviceId", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].i2cPort[I2cIdx].portId, pSSubChild1, "portId", 1, uint32_t);
I2cIdx++;
}
else if(!xmlNodeIsText(pSSubChild1))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);
rc = -1;
}
pSSubChild1 = pSSubChild1->next;
}
}
else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "gpioinfo")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio, pSSubChild, "numGpio", 1, uint8_t);
uint32_t gpioIdx = 0;
if(SENSORLIB_MAX_NUM_GPIO_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio)
{
CAM_MSG(ERROR, "Number of gpio exceeds max %d", SENSORLIB_MAX_NUM_GPIO_PER_DEVICE);
rc =-1;
break;
}
xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;
while(pSSubChild1 != NULL && !rc)
{
if(gpioIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpio)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "gpio")))
{
boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].gpioType = CameraConfigXMLParseGpioSignalType(pSSubChild1);
if (CAMERA_GPIO_MAX <= boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].gpioType)
{
CAM_MSG(ERROR, "Invalid GPIO type, exceeds %d", CAMERA_GPIO_MAX);
rc = -1;
break;
}
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].num, pSSubChild1, "num", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].config, pSSubChild1, "config", 1, uint32_t);
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioConfig[gpioIdx].configMask, pSSubChild1, "configMask", 1, uint32_t);
gpioIdx++;
}
else if(!xmlNodeIsText(pSSubChild1))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);
rc = -1;
}
pSSubChild1 = pSSubChild1->next;
}
}
else if(!(xmlStrcmp(pSSubChild->name, (const xmlChar *) "intrinfo")))
{
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr, pSSubChild, "numGpioIntr", 1, uint8_t);
uint32_t gpioIntrIdx = 0;
if(SENSORLIB_MAX_NUM_INTR_PER_DEVICE <= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr)
{
CAM_MSG(ERROR, "Number of gpio intr exceeds max %d", SENSORLIB_MAX_NUM_INTR_PER_DEVICE);
rc =-1;
break;
}
xmlNodePtr pSSubChild1 = pSSubChild->xmlChildrenNode;
while(pSSubChild1 != NULL && !rc)
{
if(gpioIntrIdx >= boardInfo->cameraLib[cameraLibIdx].devices[devId].numGpioIntr)
{
CAM_MSG(HIGH, "Number of cameraLibs exceeds max");
break;
}
if(!(xmlStrcmp(pSSubChild1->name, (const xmlChar *) "intr")))
{
boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrType = CameraConfigXMLParseIntrType(pSSubChild1);
if(CAMERA_GPIO_INTR_MAX <= boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrType)
{
CAM_MSG(ERROR, "Invalid intr type, exceeds %d", CAMERA_GPIO_INTR_MAX);
rc = -1;
break;
}
XML_GET_INT_ATTR(boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].gpioPin, pSSubChild1, "gpioPin", 1, uint32_t);
boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].triggerType = CameraConfigXMLParsetriggerType(pSSubChild1);
boardInfo->cameraLib[cameraLibIdx].devices[devId].gpioIntrConfig[gpioIntrIdx].intrMode = CameraConfigXMLParseintrMode(pSSubChild1);
gpioIntrIdx++;
}
else if(!xmlNodeIsText(pSSubChild1))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild1->name, pSSubChild->name);
rc = -1;
}
pSSubChild1 = pSSubChild1->next;
}
}
else if(!xmlNodeIsText(pSSubChild))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSSubChild->name, pSubChild->name);
rc = -1;
}
pSSubChild = pSSubChild->next;
}
devId++;
}
else if(!xmlNodeIsText(pSubChild))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pSubChild->name, pChild->name);
rc = -1;
}
pSubChild = pSubChild->next;
}
}
else if(!xmlNodeIsText(pChild))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pChild->name, pCur->name);
rc = -1;
}
pChild = pChild->next;
}
cameraLibIdx++;
}
else if(!xmlNodeIsText(pCur))
{
CAM_MSG(ERROR, "CameraConfig %s inside %s", pCur->name, pParent->name);
rc = -1;
}
pCur = pCur->next;
}
return rc;
}
/* ---------------------------------------------------------------------------
* FUNCTION SensorPlatformInit
* DESCRIPTION Initialize sensor platform with dev id
* DEPENDENCIES None
* PARAMETERS
* RETURN VALUE sensor platform ctxt ptr
* SIDE EFFECTS None
* ------------------------------------------------------------------------ */
SensorPlatform* SensorPlatform::SensorPlatformInit(const CameraConfigSensorLib_t* pDeviceConfig)
{
SensorPlatformCommon* pCtxt = new SensorPlatformCommon(pDeviceConfig);
if (pCtxt)
{
CamStatus_e rc = pCtxt->Init();
if (CAMERA_SUCCESS != rc)
{
delete pCtxt;
pCtxt = NULL;
}
}
return pCtxt;
}
/* --------------------------------------------------------------------------
** Internal Functions
** ----------------------------------------------------------------------- */
SensorPlatformCommon::SensorPlatformCommon(const CameraConfigSensorLib_t* pSensorLibConfig)
{
m_pConfig = pSensorLibConfig;
m_pHndl = NULL;
m_sensorLibId = m_pConfig->sensorLibId;
#if 0
m_i2cMutex = NULL;
memset(m_aInterrupts, 0x0, sizeof(m_aInterrupts));
#endif
}
//初始化SensorLibDeviceConfig_t中解串器GPIO的配置信息
/**
* @brief Initialize SensorPlatform
**/
CamStatus_e SensorPlatformCommon::Init()
{
CamStatus_e rc = CAMERA_SUCCESS;
QCX_LOG(SENSOR_MGR, HIGH, "SensorPlatform init camera id %d", m_sensorLibId);
for (uint32_t devIdx = 0; devIdx < m_pConfig->numDevices && CAMERA_SUCCESS == rc; devIdx++)
{
//初始化SensorLibDeviceConfig_t中解串器GPIO的配置信息
const SensorLibDeviceConfig_t* pDevice = &m_pConfig->devices[devIdx];
for (uint32_t i = 0; i < pDevice->numGpio && CAMERA_SUCCESS == rc; i++)
{
rc = PLM_GpioConfig(pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config, pDevice->gpioConfig[i].configMask);
if (CAMERA_SUCCESS != rc)
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to config GPIO %d to 0x%x",
pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config);
}
else
{
QCX_LOG(SENSOR_MGR, HIGH, "Config GPIO %d to 0x%x",
pDevice->gpioConfig[i].num, pDevice->gpioConfig[i].config);
}
}
}
return rc;
}
//加载sensorlib驱动
//调用sensorlib 注册的SensorLibraryAPI_t sg_sensorLibApi 回调函数
/**
* @brief Loads sensor library and its interface
*
* @param pSensorLib pointer to sensor lib struct
*
* @return #CamStatus_e
*/
CamStatus_e SensorManager::LoadSensorLib(QcxSensorLib_t* pSensorLib)
{
CamStatus_e result = CAMERA_SUCCESS;
/* Load sensor library, dlsym getinterface and acquire it */
#ifdef CAM_CFG_BUILD_STATIC_DEVICES
pSensorLib->pfnGetSensorLibInterface = pSensorLib->pSensorLibConfig->driverInfo.pfnSensorLibGetInterf;
pSensorLib->hLibrary = nullptr;
#else
//加载sensorlib驱动
if (nullptr == (pSensorLib->hLibrary = dlopen(pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName, RTLD_NOW|RTLD_GLOBAL)))
{
QCX_LOG(SENSOR_MGR, ERROR, "'%s' loading failed '%s'",
pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName,
dlerror());
result = CAMERA_EUNABLETOLOAD;
}
else if (NULL == (pSensorLib->pfnGetSensorLibInterface = reinterpret_cast(
dlsym(pSensorLib->hLibrary, pSensorLib->pSensorLibConfig->driverInfo.strSensorLibGetInterfFcn))))
{
QCX_LOG(SENSOR_MGR, ERROR, "'%s' interface not found '%s'",
pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName,
dlerror());
result = CAMERA_EUNABLETOLOAD;
}
else
{
//CAMERA_SUCCESS case
}
#endif
if (CAMERA_SUCCESS == result)
{ //调用sensorlib 注册的SensorLibraryAPI_t sg_sensorLibApi 回调函数
if (nullptr == (pSensorLib->pInterface = pSensorLib->pfnGetSensorLibInterface()))
{
QCX_LOG(SENSOR_MGR, ERROR, "'%s' bad init interface",
pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName);
result = CAMERA_EUNABLETOLOAD;
}
else if ((pSensorLib->pInterface->size != sizeof(SensorLibraryAPI_t)) ||
(pSensorLib->pInterface->majorVersion != SENSOR_LIB_VERSION_MAJOR) ||
(pSensorLib->pInterface->minorVersion != SENSOR_LIB_VERSION_MINOR) ||
(nullptr == pSensorLib->pInterface->Open) ||
(nullptr == pSensorLib->pInterface->Close) ||
(nullptr == pSensorLib->pInterface->Ioctl) ||
(nullptr == pSensorLib->pInterface->RegisterCallback))
{
QCX_LOG(SENSOR_MGR, ERROR, "'%s' bad interface",
pSensorLib->pSensorLibConfig->driverInfo.strSensorLibraryName);
QCX_LOG(SENSOR_MGR, ERROR, "%d %d %d %p %p %p %p",
pSensorLib->pInterface->size,
pSensorLib->pInterface->majorVersion,
pSensorLib->pInterface->minorVersion,
pSensorLib->pInterface->Open,
pSensorLib->pInterface->Close,
pSensorLib->pInterface->Ioctl,
pSensorLib->pInterface->RegisterCallback);
result = CAMERA_EUNABLETOLOAD;
}
else
{
//CAMERA_SUCCESS case
}
}
return result;
}
//调用解串器open函数接口进行初始化
//发送对应的event信号触发SensorManager::DetectHandlerThread 进行detect 操作
/**
* @brief opens instance of sensor library and registers callback
*
* @param pSensorLib pointer to sensor lib struct
*
* @return #CamStatus_e
*/
CamStatus_e SensorManager::OpenSensorLib(QcxSensorLib_t* const pSensorLib)
{
CamStatus_e result = CAMERA_SUCCESS;
SensorLibOpenParams_t openParam = {};
openParam.sensorLibId = pSensorLib->pSensorLibConfig->sensorLibId;
openParam.pPlatformFunc = &m_SensorPlatformApi;
openParam.numDevices = pSensorLib->pSensorLibConfig->numDevices;
openParam.pDevConfig = pSensorLib->pSensorLibConfig->devices;
//调用解串器open函数接口进行初始化
pSensorLib->hSensorLib = pSensorLib->pInterface->Open(&openParam);
if (nullptr == pSensorLib->hSensorLib)
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to open instance of sensorlibId %d", openParam.sensorLibId);
result = CAMERA_EFAILED;
}
else
{
//register sensor lib handle
pSensorLib->pSensorPlatform->SetSensorLibHandle(pSensorLib->hSensorLib);
SensorRet_e ret = pSensorLib->pInterface->RegisterCallback(pSensorLib->hSensorLib, SensorLibEventCallback, this);
if (SENSOR_RET_SUCCESS != ret)
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to register callback of sensorlibId %d %d", openParam.sensorLibId, ret);
result = CAMERA_EFAILED;
pSensorLib->pInterface->Close(pSensorLib->hSensorLib);
pSensorLib->hSensorLib = nullptr;
}
}
return result;
}
/**
* @brief Detect all sensorlib devices and subdevices
*
*
* @return #CamStatus_e
*/
CamStatus_e SensorManager::DetectAll(void)
{
QCXInputEventMsgType sDetect[m_numSensorLibs] = {};
QCX_LOG(SENSOR_MGR, WARN, "DetectAll %d", m_numSensorLibs);
for (uint32_t sensorlibIdx = 0U; sensorlibIdx < m_numSensorLibs; sensorlibIdx++)
{
sDetect[sensorlibIdx].eventId = INPUT_EVENT_DETECT;
sDetect[sensorlibIdx].devIdx = sensorlibIdx;
QCX_LOG(SENSOR_MGR, LOW, "threadID=%d", m_sensorLibs[sensorlibIdx].pSensorLibConfig->detectThrdId);
uint32_t const detectThrdIdx = m_sensorLibs[sensorlibIdx].pSensorLibConfig->detectThrdId % MAX_DETECT_THREAD_IDX;
//发送对应的event信号触发SensorManager::DetectHandlerThread 进行detect 操作
QueueDetectEvent(&m_detectHandler[detectThrdIdx], &sDetect[sensorlibIdx]);
}
QCXCameraWaitOnSignal(m_detectSignalDone, CAM_SIGNAL_WAIT_NO_TIMEOUT);
return CAMERA_SUCCESS;
}
CamStatus_e SensorManager::QueueDetectEvent(QCXInputDetectHandlerType* const pDetectHndlr, QCXInputEventMsgType* const pMsg)
{
CamStatus_e res = CAMERA_SUCCESS;
res = QCXQueuePush(pDetectHndlr->detectQ, static_cast(pMsg), static_cast(sizeof(pMsg)));
if (CAMERA_SUCCESS == res)
{
res = QCXCameraSetSignal(pDetectHndlr->signal);
}
else
{
QCX_LOG(SENSOR_MGR, ERROR, "failed to push to Queue");
}
return res;
}
/**
* @brief Detect Handler Thread
*
* @param pDetectHndlr QCXInputDetectHandlerType
*
* @return #CamStatus_e
*/
int SensorManager::DetectHandlerThread(void* const pArg)
{
QCXInputDetectHandlerType* const pDetectHndlr = (QCXInputDetectHandlerType*)pArg;
SensorManager* const pCtxt = GetInstance();
if (pDetectHndlr)
{
while(!pCtxt->m_detectHandlerIsExit)
{
QCX_LOG(SENSOR_MGR, LOW, "AWAKE THREAD");
pCtxt->ProcessDetectEvent(pDetectHndlr);
QCX_LOG(SENSOR_MGR, LOW, "WAIT");
QCXCameraWaitOnSignal(pDetectHndlr->signal, CAM_SIGNAL_WAIT_NO_TIMEOUT);
}
QCX_LOG(SENSOR_MGR, WARN, "THREAD DONE");
}
return 0;
}
/**
* @brief Process the Event for each thread
*
* @param pDetectHndlr QCXInputDetectHandlerType
*
* @return #CamStatus_e
*/
CamStatus_e SensorManager::ProcessDetectEvent(QCXInputDetectHandlerType* const pDetectHndlr)
{
QCXInputEventMsgType msg= {};
uint64_t size;
CamStatus_e ret = CAMERA_SUCCESS;
ret = QCXQueuePop(pDetectHndlr->detectQ, &msg, &size);
if (size == 0 || sizeof(msg) != size || ret != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, LOW, "Empty Queue");
}
if (INPUT_EVENT_DETECT == msg.eventId)
{
ret = SensorManager::GetInstance()->DetectInput(msg.devIdx);
if (ret != CAMERA_SUCCESS)
{
QCX_LOG(SENSOR_MGR, WARN, "Detect Fail on %d ", msg.devIdx);
}
}
return ret;
}
//使用ioctl 对sensor 进行上电 MAX96712Ioctl
/**
* @brief Detects specific sensor lib devices and subdevices
* @param sensorlibIdx Sensor Library Index
*
* @return #CamStatus_e
*/
CamStatus_e SensorManager::DetectInput(uint32_t sensorlibIdx)
{
CamStatus_e result = CAMERA_SUCCESS;
QcxSensorLib_t* const pSensorLib = &m_sensorLibs[sensorlibIdx];
SensorRet_e ret = SENSOR_RET_SUCCESS;
QCX_LOG(SENSOR_MGR, HIGH, "Detect sensorlibIdx %d", sensorlibIdx);
if (nullptr == pSensorLib->pInterface)
{
QCX_LOG(SENSOR_MGR, ERROR, "No interface for sensorlibIdx %d", sensorlibIdx);
DetectIncrement();
return CAMERA_ENOTFOUND;
}
SensorLibPowerCtrl_t powerCtrl = {};
//配置power cmd
powerCtrl.cmd = SENSORLIB_PWRCMD_POWER_ON;
//使用ioctl 对sensor 进行上电 MAX96712Ioctl
ret = pSensorLib->pInterface->Ioctl(
pSensorLib->hSensorLib,
SENSORLIB_CMD_POWER_CTRL,
&powerCtrl, sizeof(powerCtrl), nullptr, 0);
if (SENSOR_RET_SUCCESS != ret)
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to power on input device %d rc=%d", sensorlibIdx, ret);
result = CAMERA_EFAILED;
}
else
{
pSensorLib->m_InputDevices[0].state = QCX_INPUT_STATE_ON;
}
if (CAMERA_SUCCESS == result)
{
QCX_KPI_LOG("QCXSERVER Deserailiser Detect Start (%d)", sensorlibIdx);
//max96712_sensor_detect_device & max96712_sensor_detect_device_channels & max96712_sensor_init_setting
ret = pSensorLib->pInterface->Ioctl(pSensorLib->hSensorLib,
SENSORLIB_CMD_DETECT,
nullptr, 0,
nullptr, 0);
QCX_KPI_LOG("QCXSERVER Deserailiser Detect End (%d)", sensorlibIdx);
if (SENSOR_RET_SUCCESS == ret)
{
pSensorLib->m_InputDevices[0].state = QCX_INPUT_STATE_DETECTED;
}
else
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to detect sensorlibId %d", pSensorLib->pSensorLibConfig->sensorLibId);
result = CAMERA_EFAILED;
}
}
if (CAMERA_SUCCESS == result)
{
SensorLibEnumSubDevices_t* const pEnumSubdevices = &pSensorLib->m_InputDevices[0].enumSubdevices;
pEnumSubdevices->devId = 0U;
//max96712_enum_subdevices
ret = pSensorLib->pInterface->Ioctl(pSensorLib->hSensorLib,
SENSORLIB_CMD_ENUM_SUBDEVICES,
pEnumSubdevices, sizeof(*pEnumSubdevices),
pEnumSubdevices, sizeof(*pEnumSubdevices));
if (SENSOR_RET_SUCCESS == ret)
{
QCX_LOG(SENSOR_MGR, WARN, "Detected sensor lib %d num subdevs %d",
pSensorLib->pSensorLibConfig->sensorLibId, pEnumSubdevices->numSubDevices);
for (uint32_t subdevIdx = 0U; subdevIdx < pEnumSubdevices->numSubDevices; subdevIdx++)
{
SensorLibSubDevice_t* pSubDev = &pEnumSubdevices->subDevices[subdevIdx];
QCX_LOG(SENSOR_MGR, WARN, "%d %d %d %d",
pSensorLib->pSensorLibConfig->sensorLibId, pSubDev->devId, pSubDev->subdevId, pSubDev->state);
for (uint32_t idx = 0U; idx < m_nInputMapping; idx++)
{
QcxInputMapping_t* const pInputMap = &m_InputMappingTable[idx];
if ((pSensorLib->pSensorLibConfig->sensorLibId == pInputMap->pInfo->sensorLibId) &&
(pSubDev->devId == pInputMap->pInfo->devId) &&
(pSubDev->subdevId == pInputMap->pInfo->subdevId))
{
QCX_LOG(SENSOR_MGR, WARN, "Input %u %s available", pInputMap->pInfo->qcarcamId, pInputMap->pInfo->name);
pInputMap->sensorlibIdx = sensorlibIdx;
pInputMap->isAvailable = TRUE;
}
}
}
}
else
{
QCX_LOG(SENSOR_MGR, ERROR, "Failed to enumerate subdevices sensorlibId %d", pSensorLib->pSensorLibConfig->sensorLibId);
result = CAMERA_EFAILED;
}
}
DetectIncrement();
return result;
}