Tool/software:
HI TI
我们现在porting 一个新sensor遇到问题,log上报错是没有收到图,屏幕显示花屏。setting是有验证过ok的,之前跟贵司fae Adam有过沟通,分析可能接的csi口没有按照贵司建议的来接,我们硬件重做了转板,现在是完全按照贵司的解法接的,依旧跟之前一样的报错。请协助帮忙debug。目前iic通信正常,帧率分辨率已确认正确,mipi速率也是够的。
log和驱动代码上传至附件。sdk用的是ti-processor-sdk-rtos[com COM13] (2025-04-15_131227) COM13 (USB Serial Port (COM13)).log
/*
*
* Copyright (c) 2020 Texas Instruments Incorporated
*
* All rights reserved not granted herein.
*
* Limited License.
*
* Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
* license under copyrights and patents it now or hereafter owns or controls to make,
* have made, use, import, offer to sell and sell ("Utilize") this software subject to the
* terms herein. With respect to the foregoing patent license, such license is granted
* solely to the extent that any such patent is necessary to Utilize the software alone.
* The patent license shall not apply to any combinations which include this software,
* other than combinations with devices manufactured by or for TI ("TI Devices").
* No hardware patent is licensed hereunder.
*
* Redistributions must preserve existing copyright notices and reproduce this license
* (including the above copyright notice and the disclaimer and (if applicable) source
* code license limitations below) in the documentation and/or other materials provided
* with the distribution
*
* Redistribution and use in binary form, without modification, are permitted provided
* that the following conditions are met:
*
* * No reverse engineering, decompilation, or disassembly of this software is
* permitted with respect to any software provided in binary form.
*
* * any redistribution and use are licensed by TI for use only with TI Devices.
*
* * Nothing shall obligate TI to provide you with source code for the software
* licensed and provided to you in object code.
*
* If software source code is provided to you, modification and redistribution of the
* source code are permitted provided that the following conditions are met:
*
* * any redistribution and use of the source code, including any resulting derivative
* works, are licensed by TI for use only with TI Devices.
*
* * any redistribution and use of any object code compiled from the source code
* and any resulting derivative works, are licensed by TI for use only with TI Devices.
*
* Neither the name of Texas Instruments Incorporated nor the names of its suppliers
*
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* DISCLAIMER.
*
* THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "iss_sensor_imx390.h"
#include "imx390_serdes_config.h"
static IssSensor_CreateParams imx390CreatePrms = {
SENSOR_SONY_IMX390_UB953_D3, /*sensor name*/
0x5, /*i2cInstId*/
{
SENSOR_0_I2C_ALIAS, SENSOR_1_I2C_ALIAS, SENSOR_2_I2C_ALIAS, SENSOR_3_I2C_ALIAS,
SENSOR_4_I2C_ALIAS, SENSOR_5_I2C_ALIAS, SENSOR_6_I2C_ALIAS, SENSOR_7_I2C_ALIAS,
SENSOR_8_I2C_ALIAS, SENSOR_9_I2C_ALIAS, SENSOR_10_I2C_ALIAS, SENSOR_11_I2C_ALIAS
},/*i2cAddrSensor*/
{
SER_0_I2C_ALIAS, SER_1_I2C_ALIAS, SER_2_I2C_ALIAS, SER_3_I2C_ALIAS,
SER_4_I2C_ALIAS, SER_5_I2C_ALIAS, SER_6_I2C_ALIAS, SER_7_I2C_ALIAS,
SER_8_I2C_ALIAS, SER_9_I2C_ALIAS, SER_10_I2C_ALIAS, SER_11_I2C_ALIAS
},/*i2cAddrSer*/
/*IssSensor_Info*/
{
{
IMX390_OUT_WIDTH, /*width*/
IMX390_OUT_HEIGHT-IMX390_META_HEIGHT_AFTER, /*height*/
1, /*num_exposures*/
vx_false_e, /*line_interleaved*/
{
{TIVX_RAW_IMAGE_16_BIT, 11}, /*dataFormat and MSB [0]*/
},
0, /*meta_height_before*/
IMX390_META_HEIGHT_AFTER, /*meta_height_after*/
},
ISS_SENSOR_IMX390_FEATURES, /*features*/
ALGORITHMS_ISS_AEWB_MODE_AEWB, /*aewbMode*/
30, /*fps*/
4, /*numDataLanes*/
{1, 2, 3, 4}, /*dataLanesMap*/
{0, 0, 0, 0}, /*dataLanesPolarity*/
CSIRX_LANE_BAND_SPEED_1350_TO_1500_MBPS, /*csi_laneBandSpeed*/
},
12, /*numChan*/
390, /*dccId*/
};
static IssSensorFxns im390SensorFxns = {
IMX390_Probe,
IMX390_Config,
IMX390_StreamOn,
IMX390_StreamOff,
IMX390_PowerOn,
IMX390_PowerOff,
IMX390_GetExpParams,
IMX390_SetAeParams,
IMX390_GetDccParams,
IMX390_InitAewbConfig,
IMX390_GetIspConfig,
IMX390_ReadWriteReg,
IMX390_GetExpPrgFxn,
IMX390_deinit,
IMX390_GetWBPrgFxn,
IMX390_SetAwbParams
};
static IssSensorIntfParams imx390SensorIntfPrms = {
0, /*sensorBroadcast*/
0, /*enableFsin*/
0, /*numCamerasStreaming*/
};
IssSensorConfig imx390SensorRegConfigLinear = {
max9296DesCfg_D3IMX390, /*desCfgPreScript*/
max96717fSerCfg_D3IMX390, /*serCfgPreScript*/
iMX390LinearConfig, /*sensorCfgPreScript*/
NULL, /*desCfgPostScript*/
NULL, /*serCfgPostScript*/
NULL, /*sensorCfgPostScript*/
};
IssSensorConfig imx390SensorRegConfigWdr = {
max9296DesCfg_D3IMX390, /*desCfgPreScript*/
max96717fSerCfg_D3IMX390, /*serCfgPreScript*/
iMX390WdrConfig, /*sensorCfgPreScript*/
NULL, /*desCfgPostScript*/
NULL, /*serCfgPostScript*/
NULL, /*sensorCfgPostScript*/
};
IssSensorConfig imx390SensorRegConfigWdr60fps = {
max9296DesCfg_D3IMX390, /*desCfgPreScript*/
max96717fSerCfg_D3IMX390, /*serCfgPreScript*/
iMX390WdrConfig, /*sensorCfgPreScript*/
NULL, /*desCfgPostScript*/
NULL, /*serCfgPostScript*/
NULL, /*sensorCfgPostScript*/
};
IssSensors_Handle imx390SensorHandle = {
1, /*isUsed*/
&imx390CreatePrms, /*CreatePrms*/
&im390SensorFxns, /*SensorFxns*/
&imx390SensorIntfPrms, /*SensorIntfPrms*/
};
/*
* \brief DCC Parameters of IMX390
*/
//IssCapture_CmplxIoLaneCfg imx390Csi2CmplxIoLaneCfg;
extern IssSensors_Handle * gIssSensorTable[ISS_SENSORS_MAX_SUPPORTED_SENSOR];
static uint16_t sp1hGainRegValueOld[ISS_SENSORS_MAX_CHANNEL];
static uint16_t redGain_prev[ISS_SENSORS_MAX_CHANNEL];
static uint16_t greenGain_prev[ISS_SENSORS_MAX_CHANNEL];
static uint16_t blueGain_prev[ISS_SENSORS_MAX_CHANNEL];
int32_t IssSensor_IMX390_Init()
{
int32_t status;
int32_t chId;
status = IssSensor_Register(&imx390SensorHandle);
if(0 != status)
{
printf("IssSensor_IMX390_Init failed \n");
}
for(chId=0;chId<ISS_SENSORS_MAX_CHANNEL;chId++)
{
sp1hGainRegValueOld[chId] = 0;
redGain_prev[chId] = greenGain_prev[chId] = blueGain_prev[chId] = 512;
}
return status;
}
/*******************************************************************************
* Local Functions Definition
*******************************************************************************
*/
static int32_t IMX390_Probe(uint32_t chId, void *pSensorHdl)
{
printf("IMX390_Probe++++++++");
int32_t status = -1;
uint32_t i2cInstId;
uint8_t sensorI2cAddr;
uint16_t chipIdRegAddr = IMX390_CHIP_ID_REG_ADDR;
uint16_t chipIdRegValueRead = 0xAB;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
I2cParams * serCfg = NULL;
uint8_t count=0;
uint8_t max_retries = 1;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
i2cInstId = pCreatePrms->i2cInstId;
sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];
#if 0
serCfg = imx390SensorRegConfigWdr.serCfgPreScript;
/*The code assumes that I2C instance is the same for sensor and serializer*/
if(NULL != serCfg)
{
status = max_cfgScript(i2cInstId, pCreatePrms->i2cAddrSer[chId], serCfg);
}
/*Read chip ID to detect if the sensor can be detected*/
while( (chipIdRegValueRead != IMX390_CHIP_ID_REG_VAL) && (count < max_retries))
{
status = IMX390_ReadReg(i2cInstId, sensorI2cAddr, chipIdRegAddr, &chipIdRegValueRead, 1U);
if(status == 0 )
{
if(chipIdRegValueRead == IMX390_CHIP_ID_REG_VAL)
{
status = 0;
printf("IMX390_Probe SUCCESS : Read expected value 0x%x at chip ID register 0x%x \n", IMX390_CHIP_ID_REG_VAL, chipIdRegAddr);
}
else
{
status = -1;
printf("IMX390_Probe : 0x%x read at chip ID register 0x%x. Expected 0x%x \n", chipIdRegValueRead, chipIdRegAddr, IMX390_CHIP_ID_REG_VAL);
printf("IMX390 Probe Failed.. Retrying \n");
appLogWaitMsecs(100);
}
}
else
{
printf("IMX390 Probe : Failed to read CHIP_ID register 0x%x \n", chipIdRegAddr);
}
count++;
}
#endif
printf("IMX390_Probe----------");
return (0);
}
static int32_t IMX390_Sensor_RegConfig(uint32_t i2cInstId, uint8_t sensorI2cAddr, I2cParams *sensorCfg, uint16_t sensor_cfg_script_len)
{
int32_t status = 0;
uint16_t regAddr;
uint16_t regValue;
uint16_t delayMilliSec;
uint32_t regCnt;
if(NULL != sensorCfg)
{
regCnt = 0;
regAddr = sensorCfg[regCnt].nRegAddr;
regValue = sensorCfg[regCnt].nRegValue;
delayMilliSec = sensorCfg[regCnt].nDelay;
printf(" Configuring IMX390 imager 0x%x.. Please wait till it finishes \n", sensorI2cAddr);
while(regCnt<sensor_cfg_script_len)
{
status |= IMX390_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
if (0 != status)
{
printf(" \n \n IMX390: Sensor Reg Write Failed for regAddr 0x%x \n \n", regAddr);
}
if(delayMilliSec > 0)
{
appLogWaitMsecs(delayMilliSec);
}
regCnt++;
regAddr = sensorCfg[regCnt].nRegAddr;
regValue = sensorCfg[regCnt].nRegValue;
delayMilliSec = sensorCfg[regCnt].nDelay;
}
/*Wait 100ms after the init is done*/
appLogWaitMsecs(100);
//printf(" IMX390 config done \n ");
}
else
{
printf(" IMX390 config script is NULL \n");
}
return status;
}
static uint32_t imx390FeaturesEnabled;
static int32_t IMX390_Config(uint32_t chId, void *pSensorHdl, uint32_t sensor_features_requested)
{
int32_t status = 0;
uint32_t i2cInstId;
uint16_t sensor_cfg_script_len = 0;
uint8_t regValue = 0;
I2cParams *sensorCfg = NULL;
I2cParams *serCfg = NULL;
I2cParams *desCfg = NULL;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
if(sensor_features_requested != (sensor_features_requested & ISS_SENSOR_IMX390_FEATURES))
{
printf("IMX390_Config : Error. feature set 0x%x is not supported \n", sensor_features_requested);
return -1;
}
imx390FeaturesEnabled= sensor_features_requested;
i2cInstId = pCreatePrms->i2cInstId;
desCfg = imx390SensorRegConfigWdr.desCfgPreScript;
if(ISS_SENSOR_FEATURE_CFG_UC1 == (sensor_features_requested & ISS_SENSOR_FEATURE_CFG_UC1))
{
serCfg = imx390SensorRegConfigWdr60fps.serCfgPreScript;
sensorCfg = imx390SensorRegConfigWdr60fps.sensorCfgPreScript;
sensor_cfg_script_len = IMX390_WDR_CONFIG_SIZE;
}
else
{
if(sensor_features_requested & ISS_SENSOR_FEATURE_COMB_COMP_WDR_MODE)
{
serCfg = imx390SensorRegConfigWdr.serCfgPreScript;
sensorCfg = imx390SensorRegConfigWdr.sensorCfgPreScript;
sensor_cfg_script_len = IMX390_WDR_CONFIG_SIZE;
}else
{
serCfg = imx390SensorRegConfigLinear.serCfgPreScript;
sensorCfg = imx390SensorRegConfigLinear.sensorCfgPreScript;
sensor_cfg_script_len = IMX390_LINEAR_CONFIG_SIZE;
}
}
/*Deserializer config is done in IssSensor_PowerOn, Need to set sensor alias*/
status = max_cfgScript(i2cInstId, MAX9296_DES_ID >> 1, desCfg);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x13, ®Value);
printf("des link lock status: 0x%x\n",regValue);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x10, ®Value);
printf("des regAddr:0x10 - 0x%x\n",regValue);
if(0 != status)
{
printf("IMX390_Config Error : max9296 config failed for camera # %d \n", chId);
}
Deserializer_ReadReg(pCreatePrms->i2cAddrSer[chId], 0x00, ®Value);
printf("max96717F[ID]::0x00 - 0x%x\n",regValue);
status = max_cfgScript(i2cInstId, pCreatePrms->i2cAddrSer[chId], serCfg);
if(0 != status)
{
printf("IMX390_Config Error : UB953 config failed for camera # %d \n", chId);
}else
{
status = IMX390_Sensor_RegConfig(i2cInstId, pCreatePrms->i2cAddrSensor[chId] >> 1, sensorCfg, sensor_cfg_script_len);
}
return (status);
}
static int32_t IMX390_StreamOn(uint32_t chId, void *pSensorHdl)
{
int32_t status = 0;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
uint32_t i2cInstId;
uint8_t sensorI2cAddr;
uint32_t regCnt;
uint16_t regAddr;
uint16_t regValue;
uint8_t value;
uint16_t delayMilliSec;
I2cParams *sensorCfg = NULL;
uint16_t sensor_cfg_script_len = 0;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
if(ISS_SENSOR_FEATURE_CFG_UC1 == (imx390FeaturesEnabled& ISS_SENSOR_FEATURE_CFG_UC1))
{
if(pSenHandle->sensorIntfPrms->numCamerasStreaming >= 3U)
{
printf("IMX390_StreamOn Error : %d cameras streaming already \n", pSenHandle->sensorIntfPrms->numCamerasStreaming);
printf("IMX390_StreamOn Error : 60fps mode can support upto 3 cameras because of UB960 b/w limitation \n");
return -1;
}
}
i2cInstId = pCreatePrms->i2cInstId;
sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];
sensorCfg = imx390SensorRegConfigWdr.sensorCfgPreScript;
sensor_cfg_script_len = 10;
if(NULL != sensorCfg)
{
regCnt = 0;
regAddr = sensorCfg[regCnt].nRegAddr;
regValue = sensorCfg[regCnt].nRegValue;
delayMilliSec = sensorCfg[regCnt].nDelay;
while(regCnt<sensor_cfg_script_len)
{
printf("write IMX390 success!:regAddr 0x%x -- regValue 0x%x status = %d\n \n", regAddr, regValue, status);
status |= IMX390_ReadReg(i2cInstId, sensorI2cAddr >> 1, regAddr, ®Value, 1u);
if(delayMilliSec > 0)
{
appLogWaitMsecs(delayMilliSec);
}
if (0 == status)
{
printf("Read IMX390 success!:regAddr 0x%x -- regValue 0x%x\n \n", regAddr, regValue);
}
regCnt++;
regAddr = sensorCfg[regCnt].nRegAddr;
regValue = sensorCfg[regCnt].nRegValue;
delayMilliSec = sensorCfg[regCnt].nDelay;
}
appLogWaitMsecs(100);
}
else
{
printf("IMX390_StreamOn: IMX390 config script is NULL \n");
}
status |= IMX390_WriteReg(i2cInstId, sensorI2cAddr >> 1, 0x0100, 0x1, 1u);/*ACTIVE*/
appLogWaitMsecs(10);
status |= IMX390_ReadReg(i2cInstId, sensorI2cAddr >> 1, 0x0100, ®Value, 1u);
if (status == 0)
{
printf("read IMX390_StreamOn flag:0x0100 - 0x%x\n", regValue);
}
status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x313, 0x42);
status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x330, 0x84);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x1dc, &value);
printf("des [video lock]regAddr:0x1dc - 0x%x\n",value);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x1fc, &value);
printf("des [video lock]regAddr:0x1fc - 0x%x\n",value);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x21c, &value);
printf("des [video lock]regAddr:0x21c - 0x%x\n",value);
Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x23c, &value);
printf("des [video lock]regAddr:0x23c - 0x%x\n",value);
printf("IMX390_StreamOn End--------------------- \n");
return (status);
}
static int32_t IMX390_StreamOff(uint32_t chId, void *pSensorHdl)
{
int32_t status = 0;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
uint32_t i2cInstId;
uint8_t sensorI2cAddr;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
i2cInstId = pCreatePrms->i2cInstId;
sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];
status |= IMX390_WriteReg(i2cInstId, sensorI2cAddr >> 1, 0x0100, 0x0, 1u);/*STANDBY*/
appLogWaitMsecs(10);
status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x313, 0x40);
status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x330, 0x00);
return status;
}
static int32_t IMX390_PowerOn(uint32_t chId, void *pSensorHdl)
{
int32_t status = 0;
sp1hGainRegValueOld[chId] = 0;
redGain_prev[chId] = greenGain_prev[chId] = blueGain_prev[chId] = 512;
printf("IMX390_PowerOn : chId = 0x%x \n", chId);
return status;
}
static int32_t IMX390_PowerOff(uint32_t chId, void *pSensorHdl)
{
return (0);
}
static int32_t IMX390_SetAeParams(void *pSensorHdl, uint32_t chId, IssSensor_ExposureParams *pExpPrms)
{
uint16_t regAddr;
uint16_t cnt;
uint8_t regValue;
int32_t status = -1;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
uint32_t i2cInstId;
uint8_t sensorI2cAddr;
uint32_t sp1h_again = 0U;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
i2cInstId = pCreatePrms->i2cInstId;
sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];
/* Exp time is fixed to 11ms for LFM. Set Analog Gain Only */
for (cnt = 0; cnt < ISS_IMX390_GAIN_TBL_SIZE; cnt ++)
{
if (pExpPrms->analogGain[ISS_SENSOR_EXPOSURE_LONG] <= gIMX390GainsTable[cnt][0])
{
sp1h_again = gIMX390GainsTable[cnt][1];
break;
}
}
if(sp1hGainRegValueOld[chId] == sp1h_again)
{
/*Reduce I2C transactions.
Do not write to the sensor if register value does not change */
return 0;
}
sp1hGainRegValueOld[chId] = sp1h_again;
regAddr = 0x0008;
regValue = 1;
status = IMX390_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
if(status != 0)
{
printf("Error writing 0x%x to IMX390 register 0x%x \n", regValue, regAddr);
}
regAddr = IMX390_SP1H_ANALOG_GAIN_CONTROL_REG_ADDR;
regValue = sp1h_again & 0xFF;
status = IMX390_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
if(status != 0)
{
printf("Error writing 0x%x to IMX390 register 0x%x \n", regValue, regAddr);
}
regAddr = IMX390_SP1H_ANALOG_GAIN_CONTROL_REG_ADDR_HIGH;
regValue = sp1h_again >> 8;
status = IMX390_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
if(status != 0)
{
printf("Error writing 0x%x to IMX390 register 0x%x \n", regValue, regAddr);
}
regAddr = 0x0008;
regValue = 0;
status = IMX390_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
if(status != 0)
{
printf("Error writing 0x%x to IMX390 register 0x%x \n", regValue, regAddr);
}
return (status);
}
static int32_t IMX390_GetDccParams(uint32_t chId, void *pSensorHdl, IssSensor_DccParams *pDccPrms)
{
int32_t status = 0;
return (status);
}
static int32_t IMX390_GetExpParams(uint32_t chId, void *pSensorHdl, IssSensor_ExposureParams *pExpPrms)
{
int32_t status = 0;
assert(NULL != pExpPrms);
pExpPrms->expRatio = ISS_SENSOR_IMX390_DEFAULT_EXP_RATIO;
return (status);
}
static void IMX390_InitAewbConfig(uint32_t chId, void *pSensorHdl)
{
return;
}
static void IMX390_GetIspConfig (uint32_t chId, void *pSensorHdl)
{
return;
}
static void IMX390_deinit (uint32_t chId, void *pSensorHdl)
{
return;
}
static int32_t IMX390_ReadWriteReg (uint32_t chId, void *pSensorHdl, uint32_t readWriteFlag, I2cParams *pReg)
{
int32_t status = 0;
uint16_t regValue = 0;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pReg);
if (1u == readWriteFlag)
{
/*write*/
regValue = pReg->nRegValue;
status = IMX390_WriteReg(pCreatePrms->i2cInstId,
pCreatePrms->i2cAddrSensor[chId], pReg->nRegAddr, regValue, 1u);
}
else
{
/*read*/
status = IMX390_ReadReg(pCreatePrms->i2cInstId,
pCreatePrms->i2cAddrSensor[chId], pReg->nRegAddr, ®Value, 1u);
if (0 == status)
{
pReg->nRegValue = regValue;
}
}
return (status);
}
static int32_t IMX390_ReadReg(uint8_t i2cInstId,
uint8_t i2cAddr,
uint16_t regAddr,
uint16_t *regVal,
uint32_t numRegs)
{
int32_t status = -1;
I2C_Handle sensorI2cHandle = NULL;
static uint8_t sensorI2cByteOrder = 0U;
uint8_t readReg8_High = 0xAB;
uint8_t readReg8_Low = 0xCD;
uint32_t count;
getIssSensorI2cInfo(&sensorI2cByteOrder, &sensorI2cHandle);
if(NULL == sensorI2cHandle)
{
printf("Sensor I2C Handle is NULL \n");
return -1;
}
for(count = 0;count<numRegs;count++)
{
status = Board_i2c16BitRegRd(sensorI2cHandle, i2cAddr, regAddr, &readReg8_High, 1U, sensorI2cByteOrder, SENSOR_I2C_TIMEOUT);
if(status == 0 )
{
status = Board_i2c16BitRegRd(sensorI2cHandle, i2cAddr, regAddr+1, &readReg8_Low, 1U, sensorI2cByteOrder, SENSOR_I2C_TIMEOUT);
}
}
*regVal = ((readReg8_High << 8) & 0xFF00) | readReg8_Low;
return (status);
}
static int32_t IMX390_WriteReg(uint8_t i2cInstId,
uint8_t i2cAddr,
uint16_t regAddr,
uint16_t regVal,
uint32_t numRegs)
{
int32_t status = 0;
int16_t ret = 0;
I2C_Handle sensorI2cHandle = NULL;
static uint8_t sensorI2cByteOrder = 255u;
getIssSensorI2cInfo(&sensorI2cByteOrder, &sensorI2cHandle);
uint8_t rawRegVal[4];
I2C_Transaction transaction;
#if defined (MCU_PLUS_SDK)
I2C_Transaction_init(&transaction);
#else
I2C_transactionInit(&transaction);
#endif
if(NULL == sensorI2cHandle)
{
printf("Sensor I2C Handle is NULL \n");
return -1;
}
transaction.slaveAddress = i2cAddr;
transaction.writeBuf = rawRegVal;
transaction.writeCount = 4;
transaction.readBuf = NULL;
transaction.readCount = 0;
{
rawRegVal[0U] = (uint8_t) ((regAddr >> 8U) & (uint8_t) 0xFF);
rawRegVal[1U] = (uint8_t) ((regAddr >> 0U) & (uint8_t) 0xFF);
rawRegVal[2U] = (uint8_t) ((regVal >> 8U) & (uint8_t) 0xFF);
rawRegVal[3U] = (uint8_t) ((regVal >> 0U) & (uint8_t) 0xFF);
ret = I2C_transfer(sensorI2cHandle, &transaction);
if(ret != I2C_STS_SUCCESS)
{
printf("IMX390_WriteReg : Error writing to register 0x%x \n ", regAddr);
status = -1;
}
}
return (status);
}
static int32_t IMX390_GetExpPrgFxn(uint32_t chId, void *pSensorHdl, IssAeDynamicParams *p_ae_dynPrms)
{
int32_t status = 0;
uint8_t count = 0;
p_ae_dynPrms->targetBrightnessRange.min = DEFAULT_TARGET_BRIGHTNESS_MIN;
p_ae_dynPrms->targetBrightnessRange.max = DEFAULT_TARGET_BRIGHTNESS_MAX;
p_ae_dynPrms->targetBrightness = DEFAULT_TARGET_BRIGHTNESS;
p_ae_dynPrms->threshold = DEFAULT_TARGET_THRESHOLD;
p_ae_dynPrms->exposureTimeStepSize = DEFAULT_EXPOSURE_TIME;
p_ae_dynPrms->enableBlc = DEFAULT_ENABLE_BLC;
p_ae_dynPrms->exposureTimeRange[count].min = 11000;
p_ae_dynPrms->exposureTimeRange[count].max = 11000;
p_ae_dynPrms->analogGainRange[count].min = 1024;
p_ae_dynPrms->analogGainRange[count].max = 8192;
p_ae_dynPrms->digitalGainRange[count].min = 256;
p_ae_dynPrms->digitalGainRange[count].max = 256;
count++;
p_ae_dynPrms->numAeDynParams = count;
return (status);
}
static int32_t IMX390_GetWBPrgFxn(uint32_t chId, void *pSensorHdl, IssAwbDynamicParams *p_awb_dynPrms)
{
int32_t status = 0;
p_awb_dynPrms->redGainRange.min = 512;
p_awb_dynPrms->redGainRange.max = 2048;
p_awb_dynPrms->greenGainRange.min = 512;
p_awb_dynPrms->greenGainRange.max = 2048;
p_awb_dynPrms->blueGainRange.min = 512;
p_awb_dynPrms->blueGainRange.max = 2048;
p_awb_dynPrms->sensor_pre_gain = 0;
printf("IMX390_GetWBPrgFxn: sensor_pre_gain = %d \n", p_awb_dynPrms->sensor_pre_gain);
return (status);
}
static int32_t IMX390_SetAwbParams(void *pSensorHdl, uint32_t chId, IssSensor_WhiteBalanceParams *pWbPrms)
{
int32_t status = 0;
uint16_t regAddr;
uint16_t regValue;
IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
IssSensor_CreateParams * pCreatePrms;
assert(NULL != pSenHandle);
pCreatePrms = pSenHandle->createPrms;
assert(NULL != pCreatePrms);
assert(NULL != pWbPrms);
if(redGain_prev[chId] != pWbPrms->rGain[0])
{
redGain_prev[chId] = pWbPrms->rGain[0];
regAddr = IMX390_RED_GAIN_REG_L;
regValue = (pWbPrms->rGain[0]>>IMX390_ISP_GAIN_OFFSET) & 0xff;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
regAddr = IMX390_RED_GAIN_REG_H;
regValue = (pWbPrms->rGain[0]>>IMX390_ISP_GAIN_OFFSET) >> 8;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
}
if(greenGain_prev[chId] != pWbPrms->gGain[0])
{
greenGain_prev[chId] = pWbPrms->gGain[0];
regAddr = IMX390_GREEN1_GAIN_REG_L;
regValue = (pWbPrms->gGain[0]>>IMX390_ISP_GAIN_OFFSET) & 0xff;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
regAddr = IMX390_GREEN2_GAIN_REG_L;
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
regAddr = IMX390_GREEN1_GAIN_REG_H;
regValue = (pWbPrms->gGain[0]>>IMX390_ISP_GAIN_OFFSET) >> 8;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
regAddr = IMX390_GREEN2_GAIN_REG_H;
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
}
if(blueGain_prev[chId] != pWbPrms->bGain[0])
{
blueGain_prev[chId] = pWbPrms->bGain[0];
regAddr = IMX390_BLUE_GAIN_REG_L;
regValue = (pWbPrms->bGain[0]>>IMX390_ISP_GAIN_OFFSET) & 0xff ;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
regAddr = IMX390_BLUE_GAIN_REG_H;
regValue = (pWbPrms->bGain[0]>>IMX390_ISP_GAIN_OFFSET) >> 8;/*Sensor gain is Q8, ISP gain is Q10*/
status |= IMX390_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
}
return (status);
}