This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

J721EXCPXEVM: porting sensor fail ,The soc end cannot receive the graph

Part Number: J721EXCPXEVM

Tool/software:

Hi Ti 

When I was bring up the module s5k3b6s+max96717+ max9296, the iic communication was normal and the image receiver was normal. I confirmed that the setting was written normally, but the soc did not receive the appropriate image. May I ask if your company has some Settings for the mipi signal to ensure that the soc can receive the image correctly? Currently running singlecam, the mipi waveform with a period of 33ms can be measured at the deserter end.

I try to move entire sensor and deserializer configuration in streamon callback, It couldn't be improved either. The error was the same as before, and the soc didn't receive the graph

Error log:

VX_ZONE_WARNING:[tivxCaptureSetTimeout:795] CAPTURE: WARNING: Error frame not provided using tivxCaptureRegisterErrorFrame, defaulting to waiting forever !!!

log and driver code are uploaded  as above

The sdk uses i-processor-sdk-rtos-j721s2-evm-09_02_00_05

[com COM21] (2025-04-21_160317) COM21 (USB Serial Port (COM21)).log4478.iss_sensors.c

/*
 *
 * 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_ar0820.h"
#include "ar0820_serdes_config.h"

#define AR0820_MAX_COARSE_AGAIN (8U)
#define AR0820_MAX_FINE_AGAIN (2U)

static IssSensor_CreateParams  ar0820CreatePrms = {
    SENSOR_ONSEMI_AR0820_UB953_LI,     /*sensor name*/
    0x5,                             /*i2cInstId*/
    {
        0x10, 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
    },/*i2cAddrSensor*/
    {
        0x40, 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
    },/*i2cAddrSer*/
    /*IssSensor_Info*/
    {
        {
            AR0820_OUT_WIDTH,               /*width*/
            AR0820_OUT_HEIGHT,              /*height*/
            1,                              /*num_exposures*/
            vx_false_e,                     /*line_interleaved*/
            {
                {TIVX_RAW_IMAGE_16_BIT, 11},    /*dataFormat and MSB [0]*/
            },
            0,                              /*meta_height_before*/
            0,                              /*meta_height_after*/
        },
        ISS_SENSOR_AR0820_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*/
    },
    1,                                  /*numChan*/
    820,                                /*dccId*/
};

static IssSensorFxns           ar0820SensorFxns = {
    AR0820_Probe,
    AR0820_Config,
    AR0820_StreamOn,
    AR0820_StreamOff,
    AR0820_PowerOn,
    AR0820_PowerOff,
    AR0820_GetExpParams,
    AR0820_SetAeParams,
    AR0820_GetDccParams,
    AR0820_InitAewbConfig,
    AR0820_GetIspConfig,
    AR0820_ReadWriteReg,
    AR0820_GetExpPrgFxn,
    AR0820_deinit,
    NULL,
    NULL
};

static IssSensorIntfParams     ar0820SensorIntfPrms = {
    0,             /*sensorBroadcast*/
    0,             /*enableFsin*/
    0,               /*numCamerasStreaming*/
};

IssSensorConfig     ar0820SensorRegConfigLinear = {
    max9296DesCfg_AR0820,     /*desCfgPreScript*/
    ub953SerCfg_AR0820,     /*serCfgPreScript*/
    ar0820LinearConfig,        /*sensorCfgPreScript*/
    ub960AR0820DesCSI2Enable,        /*desCfgPostScript*/
    NULL,                    /*serCfgPostScript*/
    NULL,                    /*sensorCfgPostScript*/
};

IssSensorConfig     ar0820SensorRegConfigWdr = {
    max9296DesCfg_AR0820,     /*desCfgPreScript*/
    ub953SerCfg_AR0820,     /*serCfgPreScript*/
    ar0820WdrConfig,        /*sensorCfgPreScript*/
    ub960AR0820DesCSI2Enable,        /*desCfgPostScript*/
    NULL,                    /*serCfgPostScript*/
    NULL,                    /*sensorCfgPostScript*/
};

IssSensors_Handle ar0820SensorHandle = {
    1,                                 /*isUsed*/
    &ar0820CreatePrms,                /*CreatePrms*/
    &ar0820SensorFxns,                /*SensorFxns*/
    &ar0820SensorIntfPrms,            /*SensorIntfPrms*/
};

/*
 * \brief DCC Parameters of AR0820
 */
IssCapture_CmplxIoLaneCfg           ar0820Csi2CmplxIoLaneCfg;

extern IssSensors_Handle * gIssSensorTable[ISS_SENSORS_MAX_SUPPORTED_SENSOR];

int32_t IssSensor_AR0820_Init()
{
    int32_t status;
    status = IssSensor_Register(&ar0820SensorHandle);
    if(0 != status)
    {
        printf("IssSensor_AR0820_Init failed \n");
    }

    return status;
}

/*******************************************************************************
 *  Local Functions Definition
 *******************************************************************************
 */

static int32_t AR0820_Probe(uint32_t chId, void *pSensorHdl)
{
    #if 0
    int32_t status = -1;
    uint32_t i2cInstId;
    uint8_t sensorI2cAddr;
    uint16_t chipIdRegAddr = AR0820_CHIP_ID_REG_ADDR;
    uint16_t chipIdRegValueRead = 0xABCD;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;
    uint8_t count=0;
    uint8_t max_retries = 5;
    I2cParams    * serCfg = NULL;

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);

    i2cInstId = pCreatePrms->i2cInstId;
    sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];

    status = UB960_SetSensorAlias(chId, AR0820_I2C_ADDR, pCreatePrms->i2cAddrSer[chId]);
    if(0 != status)
    {
        printf("AR0820_Probe : UB960_SetSensorAlias for chId %d returned %d \n", chId, status);
        return status;
    }
    appLogWaitMsecs(100);

    serCfg = ar0820SensorRegConfigWdr.serCfgPreScript;
    /*The code assumes that I2C instance is the same for sensor and serializer*/
    if(NULL != serCfg)
    {
        status = ub953_cfgScript(i2cInstId, pCreatePrms->i2cAddrSer[chId], serCfg);
    }

    appLogWaitMsecs(100);

    /*Read chip ID to detect if the sensor can be detected*/

    while( (chipIdRegValueRead != AR0820_CHIP_ID_REG_VAL) && (count < max_retries))
    {
        status = AR0820_ReadReg(i2cInstId, sensorI2cAddr, chipIdRegAddr, &chipIdRegValueRead, 1U);
        if(status == 0)
        {
            if(chipIdRegValueRead == AR0820_CHIP_ID_REG_VAL)
            {
                issLogPrintf("AR0820_Probe SUCCESS : Read expected value 0x%x at chip ID register 0x%x \n", AR0820_CHIP_ID_REG_VAL, chipIdRegAddr);
            }
            else
            {
                status = -1;
                issLogPrintf("AR0820_Probe : 0x%x read at chip ID register 0x%x. Expected 0x%x \n", chipIdRegValueRead, chipIdRegAddr, AR0820_CHIP_ID_REG_VAL);
                issLogPrintf("AR0820 Probe Failed \n");
                appLogWaitMsecs(100);
            }
        }
        else
        {
            issLogPrintf("AR0820_Probe Error : Failed reading CHIP_ID register 0x%x \n", chipIdRegAddr);
        }
        count++;
    }

    if(0 == status)
    {
        chipIdRegAddr = 0x31FE;/*Sensor Revision*/
        status = AR0820_ReadReg(i2cInstId, sensorI2cAddr, chipIdRegAddr, &chipIdRegValueRead, 1U);
        if(status == 0)
        {
            issLogPrintf("AR0820 Sensor Revision ID = 0x%x \n", chipIdRegValueRead);
        }
        else
        {
            issLogPrintf("AR0820_Probe Error : Failed reading Rev ID register 0x%x \n", chipIdRegAddr);
        }
    }
    #endif
    return (0);
}

/*Flag indicating operating mode 0:Linear, 1:WDR*/
static uint8_t ar0820_op_mode = 0;

static int32_t AR0820_Config(uint32_t chId, void *pSensorHdl, uint32_t sensor_features_requested)
{
    
    int32_t status = 0;
    #if 0
    uint32_t regCnt, i2cInstId;
    uint8_t sensorI2cAddr;
    uint16_t regAddr;
    uint16_t regValue;
    uint16_t delayMilliSec;
    uint16_t sensor_cfg_script_len = 0;
    I2cParams *sensorCfg = NULL;
    I2cParams *deserCfg = NULL;
    I2cParams *serCfg = NULL;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;
    int8_t ub960InstanceId = getUB960InstIdFromChId(chId);

    if(ub960InstanceId < 0)
    {
        printf("Invalid ub960InstanceId \n");
        return 0xFF;
    }

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);

    if(sensor_features_requested != (sensor_features_requested & ISS_SENSOR_AR0820_FEATURES))
    {
        printf("AR0820_Config : Error. feature set 0x%x is not supported \n", sensor_features_requested);
        return -1;
    }
    i2cInstId = pCreatePrms->i2cInstId;
    sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];

    if(sensor_features_requested & ISS_SENSOR_FEATURE_COMB_COMP_WDR_MODE)
    {
        deserCfg = ar0820SensorRegConfigWdr.desCfgPreScript;
        serCfg = ar0820SensorRegConfigWdr.serCfgPreScript;
        sensorCfg = ar0820SensorRegConfigWdr.sensorCfgPreScript;
        sensor_cfg_script_len = AR0820_WDR_CONFIG_SIZE;
        ar0820_op_mode = 1U;
    }else
    {
        deserCfg = ar0820SensorRegConfigLinear.desCfgPreScript;
        serCfg = ar0820SensorRegConfigLinear.serCfgPreScript;
        sensorCfg = ar0820SensorRegConfigLinear.sensorCfgPreScript;
        sensor_cfg_script_len = AR0820_LINEAR_CONFIG_SIZE;
        ar0820_op_mode = 0U;
    }

    if(NULL != deserCfg)
    {
        status = ub960_cfgScript(deserCfg, ub960InstanceId);
    }
#if 0
    /*Deserializer config is done in IssSensor_PowerOn, Need to set sensor alias*/
    status = UB960_SetSensorAlias(chId, AR0820_I2C_ADDR, pCreatePrms->i2cAddrSer[chId]);
    if(0 != status)
    {
        printf("AR0820_Config : UB960_SetSensorAlias for chId %d returned %d \n", chId, status);
    }
#endif
    if(0 == status)
    {
        appLogWaitMsecs(50);

    /*The code assumes that I2C instance is the same for sensor and serializer*/
        if(NULL != serCfg)
        {
            status = max96717_cfgScript(pCreatePrms->i2cAddrSer[chId], serCfg);
        }
        if(0 == status)
        {
            appLogWaitMsecs(50);
    

            if(NULL != sensorCfg)
            {
                issLogPrintf(" Configuring AR0820 imager .. Please wait till it finishes slaveId = 0x%x\n", sensorI2cAddr);
                for(regCnt=0; regCnt<sensor_cfg_script_len; regCnt++)
                {
                    regAddr  = sensorCfg[regCnt].nRegAddr;
                    regValue = sensorCfg[regCnt].nRegValue;
                    delayMilliSec = sensorCfg[regCnt].nDelay;
    
                    status = AR0820_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
                    if (0 != status)
                    {
                        printf(" \n \n AR0820: Sensor Reg Write Failed for regAddr 0x%x \n \n", regAddr);
                        break;
                    }
                    //printf(" \n \n AR0820: Sensor Reg Write sucess for regAddr 0x%x \n \n", regAddr);
                    
                    if (delayMilliSec > 0)
                    {
                        appLogWaitMsecs(delayMilliSec);
                    }
                    
                }
                /*Wait 10ms after the init is done*/
                appLogWaitMsecs(10);
                for(regCnt = 900; regCnt<949; regCnt++)
                {
                    regAddr  = sensorCfg[regCnt].nRegAddr;
                    regValue = sensorCfg[regCnt].nRegValue;
                    delayMilliSec = sensorCfg[regCnt].nDelay;
                    status = AR0820_ReadReg(i2cInstId, sensorI2cAddr,regAddr, &regValue, 1u);
                    if(0 != status)
                    {
                        printf(" \n \n AR0820: Sensor Reg Read Failed for regAddr 0x%x \n \n", regAddr);
                    }
                    printf(" \n \n AR0820: Sensor Reg Read sucess for regAddr 0x%x : 0x%x\n \n", regAddr, regValue);
                }
            
                issLogPrintf(" AR0820 config done\n");
            }
            else
            {
                issLogPrintf(" AR0820 config script is NULL \n");
            }

        }

    }
#endif
    return (status);
}

static int32_t AR0820_StreamOn(uint32_t chId, void *pSensorHdl)
{
    int32_t status = 0;
    uint16_t regValue;
    uint8_t  value;
    uint8_t serI2cAddr;
    uint32_t regCnt, i2cInstId;
    uint8_t sensorI2cAddr;
    uint16_t regAddr;
    uint16_t delayMilliSec;
    uint16_t sensor_cfg_script_len = 0;
    I2cParams *sensorCfg = NULL;
    I2cParams *deserCfg = NULL;
    I2cParams *serCfg = NULL;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;
    int8_t ub960InstanceId = getUB960InstIdFromChId(chId);

    if(ub960InstanceId < 0)
    {
        printf("Invalid ub960InstanceId \n");
        return 0xFF;
    }

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);

    serI2cAddr    = pCreatePrms->i2cAddrSer[chId];
    i2cInstId = pCreatePrms->i2cInstId;
    sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];

    deserCfg = ar0820SensorRegConfigWdr.desCfgPreScript;
    serCfg = ar0820SensorRegConfigWdr.serCfgPreScript;
    sensorCfg = ar0820SensorRegConfigWdr.sensorCfgPreScript;
    sensor_cfg_script_len = AR0820_WDR_CONFIG_SIZE;
    ar0820_op_mode = 1U;


    if(NULL != deserCfg)
    {
        printf("deserializer setconfig+++++++++++\n");
        status = max96717_cfgScript(MAX9296_DES_ID >> 1, deserCfg);
        printf("deserializer setconfig-----------\n");
    }
#if 0
    /*Start Streaming from sensor*/
    status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], 0x301A, 0x005C, 1u);
    if(status == 0 )
    {
        appLogWaitMsecs(10);
        status = ub960_cfgScript(ub960AR0820DesCSI2Enable, ub960InstanceId);
    }
#endif

    if(0 == status)
    {
        appLogWaitMsecs(500);

    /*The code assumes that I2C instance is the same for sensor and serializer*/
        if(NULL != serCfg)
        {
            status = max96717_cfgScript(pCreatePrms->i2cAddrSer[chId], serCfg);
        }
        if(0 == status)
        {
            appLogWaitMsecs(50);
    

            if(NULL != sensorCfg)
            {
                issLogPrintf(" Configuring AR0820 imager .. Please wait till it finishes slaveId = 0x%x\n", sensorI2cAddr);
                for(regCnt=0; regCnt<sensor_cfg_script_len; regCnt++)
                {
                    regAddr  = sensorCfg[regCnt].nRegAddr;
                    regValue = sensorCfg[regCnt].nRegValue;
                    delayMilliSec = sensorCfg[regCnt].nDelay;
    
                    status = AR0820_WriteReg(i2cInstId, sensorI2cAddr, regAddr, regValue, 1u);
                    if (0 != status)
                    {
                        printf(" \n \n AR0820: Sensor Reg Write Failed for regAddr 0x%x \n \n", regAddr);
                        break;
                    }
                    //printf(" \n \n AR0820: Sensor Reg Write sucess for regAddr 0x%x \n \n", regAddr);
                    
                    if (delayMilliSec > 0)
                    {
                        appLogWaitMsecs(delayMilliSec);
                    }
                    
                }
                /*Wait 10ms after the init is done*/
                appLogWaitMsecs(10);
                for(regCnt = 900; regCnt<949; regCnt++)
                {
                    regAddr  = sensorCfg[regCnt].nRegAddr;
                    regValue = sensorCfg[regCnt].nRegValue;
                    delayMilliSec = sensorCfg[regCnt].nDelay;
                    status = AR0820_ReadReg(i2cInstId, sensorI2cAddr,regAddr, &regValue, 1u);
                    if(0 != status)
                    {
                        printf(" \n \n AR0820: Sensor Reg Read Failed for regAddr 0x%x \n \n", regAddr);
                    }
                    printf(" \n \n AR0820: Sensor Reg Read sucess for regAddr 0x%x : 0x%x\n \n", regAddr, regValue);
                }
            
                issLogPrintf(" AR0820 config done\n");
            }
            else
            {
                issLogPrintf(" AR0820 config script is NULL \n");
            }

        }


    }
    appLogWaitMsecs(50);
    //status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x313, 0x42);
    //status |= Deserializer_WriteReg(MAX9296_DES_ID >> 1, 0x330, 0x84);
    Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x313, &value);
    printf("des [video lock]regAddr:0x313 - 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, 0x330, &value);
    printf("des [video lock]regAddr:0x330 - 0x%x\n",value);
    Deserializer_ReadReg(MAX9296_DES_ID >> 1, 0x21c, &value);
    printf("des [video lock]regAddr:0x23c - 0x%x\n",value);
    Deserializer_ReadReg(serI2cAddr, 0x112, &value);
    printf("max96717pclkdet:regAddr:0x112 - 0x%x\n",value);
    Deserializer_ReadReg(serI2cAddr, 0x55f, &value);
    printf("max96717pclkdet:regAddr:0x55f - 0x%x\n",value);
    printf("IMX390_StreamOn End--------------------- \n");
    return (status);
}

static int32_t AR0820_StreamOff(uint32_t chId, void *pSensorHdl)
{
    int32_t status = 0;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;
    int8_t ub960InstanceId = getUB960InstIdFromChId(chId);

    if(ub960InstanceId < 0)
    {
        printf("Invalid ub960InstanceId \n");
        return 0xFF;
    }

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);
#if 0
    /*Stop Streaming from sensor*/
    status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], 0x301A, 0x0058, 1u);
    if(status == 0)
    {
        appLogWaitMsecs(10);
        status = ub960_cfgScript(ub960AR0820DesCSI2Disable, ub960InstanceId);
    }
#endif
    return (status);
}

static int32_t AR0820_PowerOn(uint32_t chId, void *pSensorHdl)
{
    return 0;
}

static int32_t AR0820_PowerOff(uint32_t chId, void *pSensorHdl)
{
    return (0);
}

static uint16_t exp_time_to_rows(uint32_t integration_time, uint32_t wdr_mode)
{
    uint16_t num_rows = 0;
	uint16_t llpck = LLP;
	uint16_t pclk_mhz = PCLK_MHz;
	uint16_t num_exp = 0U;
	uint16_t num_adc = NUM_ADC;
	double   mit = (MIT)/(pclk_mhz);
	double   fit = (164U - FIT)/(2*pclk_mhz);
	double   temp1, temp2;

    if(wdr_mode == 0)
    {
    	num_exp = 1U;
    }
	else
    {
    	num_exp = NUM_EXP_WDR;
    }

	temp1 = (integration_time - fit)/llpck;
	temp2 = (temp1 - mit)/(num_exp * num_adc);
	num_rows = (uint16_t) (temp2 * pclk_mhz);
    return num_rows;
}

static uint16_t expTimePrev[ISS_SENSORS_MAX_CHANNEL];
static uint16_t analogGainPrev[ISS_SENSORS_MAX_CHANNEL];
static int32_t AR0820_SetAeParams(void *pSensorHdl, uint32_t chId, IssSensor_ExposureParams *pExpPrms)
{
    int32_t status = 0;
    uint16_t regAddr;
    uint16_t regValue;
    uint32_t analogGain = 0;
    uint8_t coarseGain = 0;
    uint8_t tmp8 = 0;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);

    if (expTimePrev[chId] != pExpPrms->exposureTime[ISS_SENSOR_EXPOSURE_LONG]) 
    {
        expTimePrev[chId] = pExpPrms->exposureTime[ISS_SENSOR_EXPOSURE_LONG];
        regAddr = AR0820_GROUP_HOLD_REG_ADDR;
        regValue = 0x1;
        status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
        if(status < 0)
        {
            printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
        }

        if(0 == ar0820_op_mode)
        {
            /*Linear Mode*/
            regAddr = SENSOR_AR0820_EXP_T1;
            regValue = exp_time_to_rows(pExpPrms->exposureTime[ISS_SENSOR_EXPOSURE_LONG], 0U);
            status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
            if(status < 0)
            {
                printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
            }
        }
        else
        {
            /*WDR mode*/
            uint32_t t1_exp_time = pExpPrms->exposureTime[ISS_SENSOR_EXPOSURE_LONG];

            regAddr = SENSOR_AR0820_EXP_T1;
            regValue = exp_time_to_rows(t1_exp_time, 1U);
            status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
            if(status < 0)
            {
               printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
            }
        }
    }

    if (analogGainPrev[chId] != pExpPrms->analogGain[ISS_SENSOR_EXPOSURE_LONG]) 
    {
        analogGainPrev[chId] = pExpPrms->analogGain[ISS_SENSOR_EXPOSURE_LONG];
        analogGain = pExpPrms->analogGain[ISS_SENSOR_EXPOSURE_LONG];

        /*Calculate coarse gain*/
        if(analogGain < 2048U)
        {
            coarseGain = 1U;
            tmp8 = 0;
        }else if(analogGain < 4096U)
        {
            coarseGain = 2U;
            tmp8 = 1;
        }else if(analogGain < 8192U)
        {
            coarseGain = 4U;
            tmp8 = 2U;
        }else
        {
            coarseGain = 8U;
            tmp8 = 3U;
        }

        regAddr = SENSOR_AR0820_COARSE_ANALOG_GAIN;
        regValue = (tmp8<<12U) | (tmp8<<8U) | (tmp8<<4U) | (tmp8);
        status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
        if(status < 0)
        {
           printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
        }

        /*Calculate fine gain*/
        regAddr = SENSOR_AR0820_FINE_ANALOG_GAIN;
        tmp8 = (16*((analogGain/coarseGain)-1024))/1024;
        regValue = (tmp8<<12U) | (tmp8<<8U) | (tmp8<<4U) | (tmp8);
        status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
        if(status < 0)
        {
           printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
        }

        regAddr = AR0820_GROUP_HOLD_REG_ADDR;
        regValue = 0x0;
        status = AR0820_WriteReg(pCreatePrms->i2cInstId, pCreatePrms->i2cAddrSensor[chId], regAddr, regValue, 1u);
        if(status < 0)
        {
            printf("AR0820_SetAeParams : Failed writing 0x%x to register 0x%x\n", regValue, regAddr);
        }
    }

    return (status);
}

static int32_t AR0820_GetDccParams(uint32_t chId, void *pSensorHdl, IssSensor_DccParams *pDccPrms)
{
    int32_t status = 0;
    return (status);
}

static int32_t AR0820_GetExpParams(uint32_t chId, void *pSensorHdl, IssSensor_ExposureParams *pExpPrms)
{
    int32_t status = 0;

    assert(NULL != pExpPrms);
    pExpPrms->expRatio = 256;

    return (status);
}

static void AR0820_InitAewbConfig(uint32_t chId, void *pSensorHdl)
{
    return;
}

static void AR0820_GetIspConfig (uint32_t chId, void *pSensorHdl)
{
    return;
}

static void AR0820_deinit (uint32_t chId, void *pSensorHdl)
{
    return;
}

static int32_t AR0820_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 = AR0820_WriteReg(pCreatePrms->i2cInstId,
            pCreatePrms->i2cAddrSensor[chId], pReg->nRegAddr, regValue, 1u);
    }
    else
    {
        /*read*/
        status = AR0820_ReadReg(pCreatePrms->i2cInstId,
            pCreatePrms->i2cAddrSensor[chId], pReg->nRegAddr, &regValue, 1u);

        if (0 == status)
        {
            pReg->nRegValue = regValue;
        }
    }
    return (status);
}

static int32_t AR0820_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 = BOARD_I2C_REG_ADDR_MSB_FIRST;
    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++)
    {
        /*Read a 16-bit value as two 8-byte values*/
        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 AR0820_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 = 0u;
    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;

    /*Assume numRegs = 1 */
    {
          /* Convert Registers address and value into 8bit array */
          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 != 1u)
          {
                printf("AR0820_WriteReg : Error writing to register 0x%x \n ", regAddr);
                status = -1;
          }
    }

    return (status);
}

static int32_t AR0820_GetExpPrgFxn(uint32_t chId, void *pSensorHdl, IssAeDynamicParams *p_ae_dynPrms)
{
    int32_t status = 0;
    uint8_t count = 0;
    /*Max 38ms Exposure time since sensor is configured at 26 fps*/
    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 = 100;
    p_ae_dynPrms->exposureTimeRange[count].max = 38000;
    p_ae_dynPrms->analogGainRange[count].min = 1024;
    p_ae_dynPrms->analogGainRange[count].max = 1024;
    p_ae_dynPrms->digitalGainRange[count].min = 256;
    p_ae_dynPrms->digitalGainRange[count].max = 256;
    count++;

    p_ae_dynPrms->exposureTimeRange[count].min = 38000;
    p_ae_dynPrms->exposureTimeRange[count].max = 38000;
    p_ae_dynPrms->analogGainRange[count].min = 1024;
    p_ae_dynPrms->analogGainRange[count].max = 15872;
    p_ae_dynPrms->digitalGainRange[count].min = 256;
    p_ae_dynPrms->digitalGainRange[count].max = 256;
    count++;

    p_ae_dynPrms->numAeDynParams = count;
    return (status);
}

#ifdef _AR0820_DEBUG_
typedef struct 
{
    uint32_t regAddr;
    char regDesc[32];
}sensorDebug;

int32_t AR0820_Debug(uint32_t chId, void *pSensorHdl)
{
    int32_t status = -1;
    uint32_t i2cInstId;
    uint8_t sensorI2cAddr;
    uint16_t regAddr;
    uint16_t regValueRead = 0xABCD;
    IssSensors_Handle * pSenHandle = (IssSensors_Handle*)pSensorHdl;
    IssSensor_CreateParams * pCreatePrms;
    uint16_t count=0;
    uint16_t  numDbgReg = 0;

    assert(NULL != pSenHandle);
    pCreatePrms = pSenHandle->createPrms;
    assert(NULL != pCreatePrms);

    i2cInstId = pCreatePrms->i2cInstId;
    sensorI2cAddr = pCreatePrms->i2cAddrSensor[chId];

    const sensorDebug ar0820RegReadList[] = {
            {0x2000, "FRAME_COUNT2"},
            {0x2002, "FRAME_COUNT"},
            {0x2008, "FRAME_STATUS"},
        };
    numDbgReg = sizeof(ar0820RegReadList)/sizeof(ar0820RegReadList[0]);

    for(count = 0; count < numDbgReg; count++ )
    {
        regAddr = ar0820RegReadList[count].regAddr;
        AR0820_ReadReg(i2cInstId, sensorI2cAddr, regAddr, &regValueRead, 1u);
        printf("AR0820 Debug Reg %d : %s, Addr 0x%x, Value 0x%x \n", count, ar0820RegReadList[count].regDesc, regAddr, regValueRead);
    }

    return (status);
}
#endif //_AR0820_DEBUG_
 

Thanks 

Peng

  • Hi Peng,

    Could you please make sure that

    - number of lanes and lane polarity are matching as per the HW connection? 

    - the output lane speed from the deserializer is matching with the speed setup in the CSIRX?

    - the output virtual channel and datatype are matching with the CSIRX configuration?

    - and finally, yes please move entire configuration in streamon callback to make sure that sensor and deserialzier are enabled only after CSIRX is configured.. 

    Regards,

    Brijesh