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.

TDA4VM: enable two camera(AR0820) with vision conformance test app

Part Number: TDA4VM
Other Parts Discussed in Thread: DS90UB953A-Q1, DS90UB913A-Q1, DS90UB933-Q1

Hi TI guys,

I am trying to enable two camera(AR0820) with vision conformance test app.

I can run one camera(AR0820) well with my vision conformance test app.

But when I want to enable two camera(AR0820), I only got black screen.

Do you know how to config the CSI_VC_MAP Register (Address 0x72)?

/* RX0 Port */
{0x4C, 0x01, 0x1},
{0x32, 0x01, 0x1}, /** Enable TX port 0 */
{0x33, 0x02, 0x1},
{0x20, 0x20, 0x1},
{0xBC, 0x00, 0x1},
{0x5C, 0xE8, 0x1},
{0x5D, 0x30, 0x1}, /** Serializer I2C Address */
{0x65, 0xE8, 0x1},
{0x5E, 0x20, 0x1}, /** Sensor I2C Address */ 
{0x66, 0x30, 0x1},
{0x6d, 0x78, 0x1}, /* PORT_CONFIG set to 00: CSI-2 Mode (DS90UB953A-Q1) **** */
{0xD5, 0xF3, 0x1}, /* Set AEQ MIN/MAX widest values*/ //????
/*The FV is equivalent to a Vertical Sync (VSYNC) while the LineValid is equivalent to a Horizontal Sync (HSYNC) input to the DS90UB913A-Q1 / DS90UB933-Q1 device */ 
{0x7c, 0x20, 0x1}, /* Normal Raw10 */
{0x72, 0x00, 0x1}, /* VC MAP to 0 */
{0x0E, 0x7F, 0x1},
{0x6E, 0x10, 0x1},
{0x6F, 0x32, 0x1},
{0xB0, 0x1C, 0x1},
{0xB1, 0x15, 0x1},
{0xB2, 0x0A, 0x1},
{0xB2, 0x00, 0x1},
/* Enable Two AR0820 camera setting.........*/
/* RX1 Port */
{0x4C, 0x12, 0x1},
{0x32, 0x01, 0x1}, /** Enable TX port 0 */
{0x33, 0x02, 0x1}, /** Enable Continuous clock mode and CSI output */
{0x20, 0x20, 0x1},
{0xBC, 0x00, 0x1},
{0x5D, 0x30, 0x1}, /** Serializer I2C Address */ 
{0x65, 0xEA, 0x1},
{0x5E, 0x20, 0x1}, /** Sensor I2C Address */ 
{0x66, 0x34, 0x1},
{0x6d, 0x78, 0x1}, /* PORT_CONFIG set to 00: CSI-2 Mode (DS90UB953A-Q1) **** */
{0xD5, 0xF3, 0x1}, /* Set AEQ MIN/MAX widest values*/ //????
{0x7c, 0x20, 0x1}, /* Raw10 low 8-bit, discard frame on Parity error */
/* Two AR0820 camera setting.........*/
{0x72, 0x55, 0x1}, /* VC MAP to 1 */
//{0x72, 0x54, 0x1}, /* VC MAP to 1 */
{0xB0, 0x1C, 0x1},
{0xB1, 0x15, 0x1},
{0xB2, 0x0A, 0x1},

I also put my codes in the attached files.

4276.DS90UB962_cfg.h

8078.test_capture_display.c

Thanks,

Jerry Ho

  • Hi Jerry,

    Are both the cameras connected to the port0 and port1? 

    As such, the configuration for both the ports in ub960 remains same, except value in 0x72 and i2c alias address for serializer and camera. This configures the VC channel mapping. 

    the above config looks correct, you are configuring ub960 to map all channels received on port0 to have VC id0 and all channels on port1 to have VC id 1. 

    In addition to ub960 configuration, do you also configure serializer and camera correctly? can you please check it?

    Regards,

    Brijesh

  • Hi Brijesh,

    1.Yes, they are.

    2. 2 serializer config, As I know,

    RX0

    {0x65, 0xE8, 0x1},

    RX1

    {0x65, 0xEA, 0x1},

    0xE8 and 0xEA would be move left one bit for getting serializer i2c address.

    3. camera sensor config,

    RX0

    {0x66, 0x30, 0x1},

    RX1

    {0x66, 0x34, 0x1},

    0x30 and 0x34 would be move left one bit for getting sensor i2c address.

    I have done this part in my app_sensors.c.

    please refer this file.

    /*
     *
     * Copyright (c) 2019 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 bina
     *
     * *       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 Files                                  */
    /* ========================================================================== */
    
    
    #include <ti/board/src/devices/board_devices.h>
    #include <ti/drv/i2c/I2C.h>
    #include <ti/drv/i2c/soc/I2C_soc.h>
    #include <ti/board/src/devices/common/common.h>
    #include <ti/board/board.h>
    
    #include <ti/board/src/devices/board_devices.h>
    #include <ti/board/src/devices/fpd/ds90ub960.h>
    
    #include <utils/sensors/include/app_sensors.h>
    #include <utils/console_io/include/app_log.h>
    
    #include <utils/remote_service/include/app_remote_service.h>
    
    #include <ti/csl/csl_gpio.h>
    #include <ti/csl/cslr.h>
    
    #include "ov2775_cfg.h"
    #include "imx390_cfg.h"
    #include "DS90UB962_cfg.h"
    #include "DS90UB936_cfg.h"
    #include "ar0820_linear_config.h"
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    static int32_t appSetupI2CInst(uint8_t i2cInst);
    static int32_t appCloseI2CInst(void);
    static int32_t appOv2775Config(AppSensorCmdParams *prms);
    static int32_t appImx390Config(AppSensorCmdParams *prms);
    static int32_t appDS90UB962Config_AR0820(AppSensorCmdParams *prms);
    static int32_t appDS90UB962Config_IMX490(AppSensorCmdParams *prms);
    static int32_t appDS90UB962Config_Normal(AppSensorCmdParams *prms);
    static int32_t appDS90UB962Config_PG(AppSensorCmdParams *prms);
    static int32_t appDS90UB936Config_Normal(AppSensorCmdParams *prms);
    static int32_t appDS90UB936Config_PG(AppSensorCmdParams *prms);
    static int32_t appDS90UB936Config_PG_2(AppSensorCmdParams *prms);
    
    int32_t appRemoteServiceSensorHandler(char *service_name, uint32_t cmd,
        void *prm, uint32_t prm_size, uint32_t flags);
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    static I2C_Handle gI2cHandle = NULL;
    
    
    /* ========================================================================== */
    /*                  Internal/Private Function Declarations                    */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    
    #if 1
    static int32_t AR0820_WrtieReg(void *handle,
    				uint8_t      i2cAddr,
    				uint16_t     regAddr,
    				uint16_t     regVal,
    				uint32_t     numRegs)
    {
    	int32_t  status = 0;
    	int16_t  ret = 0;
    	I2C_Handle sensorI2cHandle = (I2C_Handle)handle;
    	uint8_t   rawRegVal[4];
    	I2C_Transaction transaction;
    
    	I2C_transactionInit(&transaction);
    
    	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)
    		{
    			appLogPrintf("Error writing to register 0x%x \n ", regAddr);
    			status = -1;
    		}
    	}
    
    	return (status);
    }
    #endif
    
    int32_t appI2cInit()
    {
        uint32_t index;
        I2C_HwAttrs i2cConfig;
    
        /* Initialize I2C Driver */
        for(index = 0; index < I2C_HWIP_MAX_CNT; index++)
        {
            I2C_socGetInitCfg(index, &i2cConfig);
            i2cConfig.enableIntr = false;
            I2C_socSetInitCfg(index, &i2cConfig);
        }
    
        /* Initializes the I2C */
        I2C_init();
    
        return 0;
    }
    
    int32_t appI2cDeInit()
    {
        /* I2C_deInit(); */
    
        return 0;
    }
    
    int32_t appRemoteServiceSensorInit()
    {
        int32_t status = 0;
    
        status = appRemoteServiceRegister(
            APP_REMOTE_SERVICE_SENSOR_NAME, appRemoteServiceSensorHandler);
        if(status!=0)
        {
            appLogPrintf(
                " REMOTE_SERVICE_SENSOR: ERROR: Unable to register remote service sensor handler\n");
        }
        return status;
    }
    
    int32_t appRemoteServiceSensorDeInit()
    {
        int32_t status = 0;
    
        status = appRemoteServiceUnRegister(APP_REMOTE_SERVICE_SENSOR_NAME);
        if(status!=0)
        {
            appLogPrintf(
                " REMOTE_SERVICE_SENSOR: ERROR: Unable to register remote service sensor handler\n");
        }
    
        return status;
    }
    
    int32_t appRemoteServiceSensorHandler(char *service_name, uint32_t cmd,
        void *prm, uint32_t prm_size, uint32_t flags)
    {
        int32_t                 status = 0;
        AppSensorCmdParams     *cmdPrms = NULL;
    
        if ((NULL != prm) && (sizeof(AppSensorCmdParams) == prm_size))
        {
            cmdPrms = (AppSensorCmdParams *)prm;
    
            appLogPrintf(
                " REMOTE_SERVICE_SENSOR: Received command %08x to configure %d sensor(s) !!!\n",
                    cmd,
                    cmdPrms->numSensors);
    
            switch(cmd)
            {
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_OV2775:
                    status = appOv2775Config(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_IMX390:
                    status = appImx390Config(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB962_AR0820:
                    status = appDS90UB962Config_AR0820(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB962_IMX490:
                    status = appDS90UB962Config_IMX490(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB962_Normal:
                    status = appDS90UB962Config_Normal(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB962_PG:
                    status = appDS90UB962Config_PG(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB936_PG:
                    status = appDS90UB936Config_PG(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB936_Normal:
                    status = appDS90UB936Config_Normal(cmdPrms);
                    break;
                case APP_REMOTE_SERVICE_SENSOR_CMD_CONFIG_DS90UB936_PG_2:
                    status = appDS90UB936Config_PG_2(cmdPrms);
                    break;
            }
    
            if (0 == status)
            {
                appLogPrintf(
                    " REMOTE_SERVICE_SENSOR: Sensor(s) configuration done !!!\n");
            }
            else
            {
                appLogPrintf(
                    " REMOTE_SERVICE_SENSOR: ERROR: Sensor(s) configuration failed !!!\n");
            }
        }
        else
        {
            appLogPrintf(
                " REMOTE_SERVICE_SENSOR: Invalid parameters passed !!!\n");
        }
    
    
        return (status);
    }
    
    static int32_t appOv2775Config(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint32_t cnt, cnt1;
        uint32_t numSers, numSensors;
        uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint8_t desI2cAddr, i2cAddr;
        uint8_t regAddr8, regVal8;
        uint8_t i2cInst;
        uint16_t regAddr16;
    
        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_0);
    
        status = appSetupI2CInst(i2cInst);
    
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
        
        if (0 == status)
        {
            numSers = 0u;
            numSensors = 0u;
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(ov2775_ub960_cfg)/(sizeof(ov2775_ub960_cfg[0]));
                cnt ++)
            {
                regAddr8 = ov2775_ub960_cfg[cnt][0] & 0xFF;
                regVal8 = ov2775_ub960_cfg[cnt][1] & 0xFF;
    
                if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }
    
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }
    
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB960 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(ov2775_ub960_cfg[cnt][2]);
                }
            }
        }
    
        if (0 == status)
        {
            if (numSensors != numSers)
            {
                appLogPrintf(
                    " REMOTE_SERVICE_SENSOR: ERROR: Incorrect UB960 configuration\n");
                status = -1;
            }
            else
            {
                if (prms->numSensors > numSensors)
                {
                    appLogPrintf(
                        " REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors in parameters\n");
                    status = -1;
                }
            }
        }
    
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                i2cAddr = serI2cAddr[cnt1];
                for (cnt = 0;
                    cnt < sizeof(ov2775_ub953_cfg)/(sizeof(ov2775_ub953_cfg[0]));
                    cnt ++)
                {
                    regAddr8 = ov2775_ub953_cfg[cnt][0] & 0xFF;
                    regVal8 = ov2775_ub953_cfg[cnt][1] & 0xFF;
                    status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                        regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf (
                            " REMOTE_SERVICE_SENSOR: Failed to Set UB953 register %x: Value:%x\n",
                            regAddr8, regVal8);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(ov2775_ub953_cfg[cnt][2]);
                    }
                }
            }
        }
    
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                i2cAddr = sensorI2cAddr[cnt1];
                for (cnt = 0;
                    cnt < sizeof(ov2775_cfg)/sizeof(ov2775_cfg[0]); cnt ++)
                {
                    regAddr16 = ov2775_cfg[cnt][0] & 0xFFFF;
                    regVal8 = ov2775_cfg[cnt][1] & 0xFF;
    
                    status = Board_i2c16BitRegWr(gI2cHandle, i2cAddr,
                        regAddr16, &regVal8, 1, BOARD_I2C_REG_ADDR_MSB_FIRST, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf (
                            " REMOTE_SERVICE_SENSOR: Failed to Set IMX390 register %x: Value:0x%x\n",
                            regAddr16, regVal8);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(ov2775_cfg[cnt][2]);
                    }
                }
            }
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appImx390Config(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint32_t cnt, cnt1;
        uint32_t numSers, numSensors;
        uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint8_t desI2cAddr, i2cAddr;
        uint8_t regAddr8, regVal8;
        uint8_t i2cInst;
        uint16_t regAddr16;
        uint32_t portIdx;
    
        /* get I2C instance for port 0, this just to I2C instance for I2C driver Open */
        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_0);
        status = appSetupI2CInst(i2cInst);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    #if 1
        if (0 == status)
        {
            for (portIdx = 0U ; portIdx < prms->portNum ; portIdx++)
            {
                switch (prms->portIdMap[portIdx])
                {
                    case 0U:
                        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_0);
                    break;
                    case 1U:
                        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_1);
                    break;
                    default:
                        status = -1;
                    break;
                }
                if (0 == status)
                {
                    appLogPrintf(" REMOTE_SERVICE_SENSOR: IMX390: Configuring UB960 ... !!!\n");
                    numSers = 0u;
                    numSensors = 0u;
                    i2cAddr = desI2cAddr;
                    for (cnt = 0;
                        cnt < sizeof(imx390_ub960_cfg)/(sizeof(imx390_ub960_cfg[0]));
                        cnt ++)
                    {
                        regAddr8 = imx390_ub960_cfg[cnt][0] & 0xFF;
                        regVal8 = imx390_ub960_cfg[cnt][1] & 0xFF;
    
                        if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                        {
                            serI2cAddr[numSers] = regVal8 >> 1u;
                            numSers ++;
                        }
    
                        if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                        {
                            sensorI2cAddr[numSensors] = regVal8 >> 1u;
                            numSensors ++;
                        }
    
                        status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                            regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                        if (0 != status)
                        {
                            appLogPrintf (
                                " REMOTE_SERVICE_SENSOR: Failed to Set UB960 register %x: Value:%x\n",
                                regAddr8, regVal8);
                            break;
                        }
                        else
                        {
                            appLogWaitMsecs(imx390_ub960_cfg[cnt][2]);
                        }
                    }
                }
                if (0 == status)
                {
                    if (numSensors != numSers)
                    {
                        appLogPrintf(
                            " REMOTE_SERVICE_SENSOR: ERROR: Incorrect UB960 configuration\n");
                        status = -1;
                    }
                    else
                    {
                        if (prms->numSensors > numSensors)
                        {
                            appLogPrintf(
                                " REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors in parameters\n");
                            status = -1;
                        }
                    }
                }
    
                if (0 == status)
                {
                    for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
                    {
                        appLogPrintf(" REMOTE_SERVICE_SENSOR: IMX390: Configuring UB953 for sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                        i2cAddr = serI2cAddr[cnt1];
                        for (cnt = 0;
                            cnt < sizeof(imx390_ub953_cfg)/(sizeof(imx390_ub953_cfg[0]));
                            cnt ++)
                        {
                            regAddr8 = imx390_ub953_cfg[cnt][0] & 0xFF;
                            regVal8 = imx390_ub953_cfg[cnt][1] & 0xFF;
                            status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                                regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                            if (0 != status)
                            {
                                appLogPrintf (
                                    " REMOTE_SERVICE_SENSOR: Failed to Set UB953 register %x: Value:%x\n",
                                    regAddr8, regVal8);
                                break;
                            }
                            else
                            {
                                appLogWaitMsecs(imx390_ub953_cfg[cnt][2]);
                            }
                        }
                    }
                }
    
                if (0 == status)
                {
                    for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
                    {
                        appLogPrintf(" REMOTE_SERVICE_SENSOR: IMX390: Configuring sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                        i2cAddr = sensorI2cAddr[cnt1];
                        for (cnt = 0;
                            cnt < sizeof(imx390_cfg)/sizeof(imx390_cfg[0]); cnt ++)
                        {
                            regAddr16 = imx390_cfg[cnt][0] & 0xFFFF;
                            regVal8 = imx390_cfg[cnt][1] & 0xFF;
    
                            status = Board_i2c16BitRegWr(gI2cHandle, i2cAddr,
                                regAddr16, &regVal8, 1, BOARD_I2C_REG_ADDR_MSB_FIRST, BOARD_I2C_TRANSACTION_TIMEOUT);
                            if (0 != status)
                            {
                                appLogPrintf (
                                    " REMOTE_SERVICE_SENSOR: Failed to Set IMX390 register %x: Value:0x%x\n",
                                    regAddr16, regVal8);
                                break;
                            }
                            else
                            {
                                appLogWaitMsecs(imx390_cfg[cnt][2]);
                            }
                        }
                    }
                }
            }
        }
    
        if (0 == status)
        {
            for (portIdx = 0U ; portIdx < prms->portNum ; portIdx++)
            {
                switch (portIdx)
                {
                    case 0U:
                        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_0);
                    break;
                    case 1U:
                        Board_fpdU960GetI2CAddr(&i2cInst, &desI2cAddr, BOARD_CSI_INST_1);
                    break;
                    default:
                        status = -1;
                    break;
                }
                if (0 == status)
                {
                    i2cAddr = desI2cAddr;
                    regAddr8 = 0x33;
                    regVal8 = 0x3;
                    status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                        regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf ("Failed to enable CSI port\n");
                    }
                }
            }
        }
    #endif 
    
        if (0 == status)
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB962_TurnOn(void)
    {
    	int32_t regVal = 0U;
    	int32_t status = 0U;
    	/* GPIO1_26(0x26C) set output & pull high */
    	regVal = 0x50007U;
    	CSL_REG32_WR(CSL_CTRL_MMR0_CFG0_BASE + 0x1C26CU, regVal);
    	//GPIO_DIR01 0x00601010
    	GPIOSetDirMode_v0(CSL_GPIO1_BASE, 26, GPIO_DIRECTION_OUTPUT);
    	GPIOPinWrite_v0(CSL_GPIO1_BASE, 26, GPIO_PIN_HIGH);
    
    	/* GPIO0_75(0x130) set output & pull high*/
    	regVal = 0x50007U;
    	CSL_REG32_WR(CSL_CTRL_MMR0_CFG0_BASE + 0x1C130U, regVal);
    	//GPIO_DIR45 0x00600060
    	GPIOSetDirMode_v0(CSL_GPIO0_BASE, 75, GPIO_DIRECTION_OUTPUT);
    	GPIOPinWrite_v0(CSL_GPIO0_BASE, 75, GPIO_PIN_HIGH);
    
    	/* GPIO1_19(0x250) set output & pull high*/
    	regVal = 0x50007U;
    	CSL_REG32_WR(CSL_CTRL_MMR0_CFG0_BASE + 0x1C250U, regVal);
    	//GPIO_DIR01 0x00601010
    	GPIOSetDirMode_v0(CSL_GPIO1_BASE, 19, GPIO_DIRECTION_OUTPUT);
    	GPIOPinWrite_v0(CSL_GPIO1_BASE, 19, GPIO_PIN_HIGH);
    
    	return status;
    }
    
    static int32_t appDS90UB962Config_PG(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x34U;
        uint8_t i2cInst = 0U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;   
        uint32_t cnt;
     
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB962_TurnOn();
        status = appSetupI2CInst(i2cInst);
    
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(UB962_Pattern_cfg)/(sizeof(UB962_Pattern_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB962_Pattern_cfg[cnt][0] & 0xFF;
                regVal8 = UB962_Pattern_cfg[cnt][1] & 0xFF;
    
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB962 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB962_Pattern_cfg[cnt][2]);
                }
            }
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB962Config_Normal(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x34U;
        uint8_t i2cInst = 0U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;   
        uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint32_t numSers;//, numSensors;
        uint32_t cnt, cnt1;
     
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB962_TurnOn();
        status = appSetupI2CInst(i2cInst);
    
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            numSers = 0u;
            //numSensors = 0u;
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(UB962_Normal_cfg)/(sizeof(UB962_Normal_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB962_Normal_cfg[cnt][0] & 0xFF;
                regVal8 = UB962_Normal_cfg[cnt][1] & 0xFF;
    
                if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }
    	    /*
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }*/
    
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB962 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB962_Normal_cfg[cnt][2]);
                }
            }
        }
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                appLogPrintf(" REMOTE_SERVICE_SENSOR: UB962: Configuring UB913a for sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                i2cAddr = serI2cAddr[cnt1];
                for (cnt = 0;
                    cnt < sizeof(UB962_UB913a_cfg)/(sizeof(UB962_UB913a_cfg[0]));
                    cnt ++)
                {
                    regAddr8 = UB962_UB913a_cfg[cnt][0] & 0xFF;
                    regVal8 = UB962_UB913a_cfg[cnt][1] & 0xFF;
    	        appLogPrintf (
    		    " V3GA Print  Set UB913a register %x: Value:%x\n",
                        regAddr8, regVal8);
    
                    status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                        regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf (
                          " REMOTE_SERVICE_SENSOR: Failed to Set UB913a register %x: Value:%x\n",
                           regAddr8, regVal8);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(UB962_UB913a_cfg[cnt][2]);
                    }
                }
            }
        }
        if (0 == status)
        {
            i2cAddr = desI2cAddr;
            regAddr8 = 0x33;
            regVal8 = 0x43;
            status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
            if (0 != status)
            {
               appLogPrintf ("Failed to enable CSI port\n");
            }
    	appLogPrintf("V3GA Print : Enable CSI Port OK, i2cAddr=%d!!! \n", i2cAddr);
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB962Config_IMX490(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x34U;
        uint8_t i2cInst = 0U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;
        //uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint32_t numSers, numSensors;
        uint32_t cnt;//, cnt1;
    
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB962_TurnOn();
        status = appSetupI2CInst(i2cInst);
    
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            //numSers = 0u;
            //numSensors = 0u;
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(UB962_Normal_with_UB953_cfg)/(sizeof(UB962_Normal_with_UB953_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB962_Normal_with_UB953_cfg[cnt][0] & 0xFF;
                regVal8 = UB962_Normal_with_UB953_cfg[cnt][1] & 0xFF;
    
    	    /*
                if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }*/
    
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB962 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB962_Normal_with_UB953_cfg[cnt][2]);
                }
            }
        }
    #if 0 //Mark this first until we find some register in UB953 need to contorl
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                appLogPrintf(" REMOTE_SERVICE_SENSOR: UB962: Configuring UB913a for sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                i2cAddr = serI2cAddr[cnt1];
                for (cnt = 0;
                    cnt < sizeof(UB962_UB913a_cfg)/(sizeof(UB962_UB913a_cfg[0]));
                    cnt ++)
                {
                    regAddr8 = UB962_UB913a_cfg[cnt][0] & 0xFF;
                    regVal8 = UB962_UB913a_cfg[cnt][1] & 0xFF;
    	        appLogPrintf (
    		    " V3GA Print  Set UB913a register %x: Value:%x\n",
                        regAddr8, regVal8);
    
                    status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                        regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf (
                          " REMOTE_SERVICE_SENSOR: Failed to Set UB913a register %x: Value:%x\n",
                           regAddr8, regVal8);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(UB962_UB913a_cfg[cnt][2]);
                    }
                }
            }
        }
    #endif
        if (0 == status)
        {
            i2cAddr = desI2cAddr;
            regAddr8 = 0x33;
            regVal8 = 0x43;
            status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
            if (0 != status)
            {
               appLogPrintf ("Failed to enable CSI port\n");
            }
    	appLogPrintf("V3GA Print : Enable CSI Port OK, i2cAddr=%d!!! \n", i2cAddr);
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB962Config_AR0820(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x34U;
        uint8_t i2cInst = 0U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;
        uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint32_t numSers, numSensors;
        uint32_t cnt, cnt1;
        uint16_t regAddr16, regVal16;
    
        appLogPrintf("XXXX %s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB962_TurnOn();
        status = appSetupI2CInst(i2cInst);
    
        appLogPrintf("XXXX V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            numSers = 0u;
            numSensors = 0u;
            i2cAddr = desI2cAddr;
            appLogPrintf(" REMOTE_SERVICE_SENSOR: write UB962_Normal_with_AR0820_cfg!!!\n");
            for (cnt = 0;
                cnt < sizeof(UB962_Normal_with_AR0820_cfg)/(sizeof(UB962_Normal_with_AR0820_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB962_Normal_with_AR0820_cfg[cnt][0] & 0xFF;
                regVal8 = UB962_Normal_with_AR0820_cfg[cnt][1] & 0xFF;
    
                if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }
    
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB962 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB962_Normal_with_AR0820_cfg[cnt][2]);
                }
            }
        }
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                appLogPrintf(" REMOTE_SERVICE_SENSOR: UB962: Configuring UB953 for sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                i2cAddr = serI2cAddr[cnt1];
                for (cnt = 0;
                    cnt < sizeof(UB962_AR0820_cfg)/(sizeof(UB962_AR0820_cfg[0]));
                    cnt ++)
                {
                    regAddr8 = UB962_AR0820_cfg[cnt][0] & 0xFF;
                    regVal8 = UB962_AR0820_cfg[cnt][1] & 0xFF;
    	        appLogPrintf (
    		    " V3GA Print i2c add is 0x%x , Set UB953 register %x: Value:%x\n",
                        i2cAddr,regAddr8, regVal8);
    
                    status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                        regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                    if (0 != status)
                    {
                        appLogPrintf (
                          " REMOTE_SERVICE_SENSOR: Failed to Set UB953 register %x: Value:%x\n",
                           regAddr8, regVal8);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(UB962_AR0820_cfg[cnt][2]);
                    }
                }
            }
        }
    #if 1 //Mark this first until we find some register in UB953 need to contorl
        if (0 == status)
        {
            for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
            {
                appLogPrintf(" REMOTE_SERVICE_SENSOR: AR0820: Configuring sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                i2cAddr = sensorI2cAddr[cnt1];
    
                appLogPrintf(" REMOTE_SERVICE_SENSOR: AR0820: Configuring sensor i2c addr is 0x%x !!!\n", i2cAddr);
    
    	    for (cnt = 0;
                    cnt < sizeof(ar0820LinearConfig)/sizeof(ar0820LinearConfig[0]); cnt ++)
                {
                    regAddr16 = ar0820LinearConfig[cnt][0] & 0xFFFF;
                    regVal16 = ar0820LinearConfig[cnt][1] & 0xFFFF;
    
    		status = AR0820_WrtieReg(gI2cHandle, i2cAddr, regAddr16, regVal16, 1u);
                    if (0 != status)
                    {
                        appLogPrintf (
                           " REMOTE_SERVICE_SENSOR: Failed to Set AR0820 register %x: Value:0x%x\n",
                                regAddr16, regVal16);
                        break;
                    }
                    else
                    {
                        appLogWaitMsecs(ar0820LinearConfig[cnt][2]);
                    }
                }
    
    	    //V3GA Test: Add for turn on Stream
                regAddr16 = 0x301A & 0xFFFF;
                regVal16 = 0x005c & 0xFFFF;
    	    status = AR0820_WrtieReg(gI2cHandle, i2cAddr, regAddr16, regVal16, 1u);
    
    
            }
        }
    #endif
        if (0 == status)
        {
            i2cAddr = desI2cAddr;
            regAddr8 = 0x33;
            regVal8 = 0x03;
    	appLogPrintf("V3GA Print : desSerial i2cAddr=%x!!! \n", i2cAddr);
            status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
            if (0 != status)
            {
               appLogPrintf ("Failed to enable CSI port\n");
            }
    	appLogPrintf("V3GA Print : Enable CSI Port OK, i2cAddr=%x!!! \n", i2cAddr);
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB936_TurnOn(void)
    {
    	int32_t regVal = 0U;
    	int32_t status = 0U;
    	/* GPIO0_76(0x134) set output & pull high */
    	regVal = 0x50007U;
    	CSL_REG32_WR(CSL_CTRL_MMR0_CFG0_BASE + 0x1C134U, regVal);
    	//GPIO_DIR45 0x00600060
    	GPIOSetDirMode_v0(CSL_GPIO0_BASE, 76, GPIO_DIRECTION_OUTPUT);
    	GPIOPinWrite_v0(CSL_GPIO0_BASE, 76, GPIO_PIN_HIGH);
    
    	/* GPIO1_18(0x24C) set output & pull high*/
    	regVal = 0x50007U;
    	CSL_REG32_WR(CSL_CTRL_MMR0_CFG0_BASE + 0x1C24CU, regVal);
    	//GPIO_DIR01 0x00601010
    	GPIOSetDirMode_v0(CSL_GPIO1_BASE, 18, GPIO_DIRECTION_OUTPUT);
    	GPIOPinWrite_v0(CSL_GPIO1_BASE, 18, GPIO_PIN_HIGH);
    
    	return status;
    }
    
    static int32_t appDS90UB936Config_PG(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x3dU;
        uint8_t i2cInst = 3U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;   
        //uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint32_t numSers, numSensors;
        uint32_t cnt;//, cnt1;
    
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB936_TurnOn();
        status = appSetupI2CInst(i2cInst);
        
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        appLogPrintf("V3GA Print status=%d\n", status);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            //numSers = 0u;
            //numSensors = 0u;
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(UB936_Pattern_cfg)/(sizeof(UB936_Pattern_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB936_Pattern_cfg[cnt][0] & 0xFF;
                regVal8 = UB936_Pattern_cfg[cnt][1] & 0xFF;
    	    appLogPrintf (
    		" V3GA Print  Set UB936 register %x: Value:%x\n",
                   	regAddr8, regVal8);
                
    /*            if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }*/
    /*
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }
    */	
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB936 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB936_Pattern_cfg[cnt][2]);
                }
            }
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB936Config_PG_2(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x3dU;
        uint8_t i2cInst = 3U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;   
        uint32_t cnt;
    
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB936_TurnOn();
        status = appSetupI2CInst(i2cInst);
        
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        appLogPrintf("V3GA Print status=%d\n", status);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            //numSers = 0u;
            //numSensors = 0u;
            i2cAddr = desI2cAddr;
            for (cnt = 0;
                cnt < sizeof(UB936_Pattern_YUV_cfg)/(sizeof(UB936_Pattern_YUV_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB936_Pattern_YUV_cfg[cnt][0] & 0xFF;
                regVal8 = UB936_Pattern_YUV_cfg[cnt][1] & 0xFF;
    	    appLogPrintf (
    		" V3GA Print  Set UB936 register %x: Value:%x\n",
                   	regAddr8, regVal8);
                
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB936 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB936_Pattern_YUV_cfg[cnt][2]);
                }
            }
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    static int32_t appDS90UB936Config_Normal(AppSensorCmdParams *prms)
    {
        int32_t status = 0U;
        uint8_t desI2cAddr = 0x3dU;
        uint8_t i2cInst = 3U;
        uint8_t i2cAddr;
        uint8_t regAddr8, regVal8;   
        uint8_t serI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        //uint8_t sensorI2cAddr[APP_MAX_SENSORS] = { 0 } ;
        uint32_t numSers; //, numSensors;
        uint32_t cnt, cnt1;
    
        appLogPrintf("%s[%d]V3GA Print \n", __func__, __LINE__);
        status = appDS90UB936_TurnOn();
        status = appSetupI2CInst(i2cInst);
        
        appLogPrintf("V3GA Print sensor=%d, MAX=%d, port=%d, MAX_Port=%d\n", prms->numSensors, APP_MAX_SENSORS, prms->portNum, APP_PORT_NUM_MAX);
        appLogPrintf("V3GA Print status=%d\n", status);
        /* Check for maximum number of sensors & no. of ports supported */
        if (prms->numSensors > APP_MAX_SENSORS || prms->portNum > APP_PORT_NUM_MAX)
        {   
            appLogPrintf(" REMOTE_SERVICE_SENSOR: ERROR: Incorrect Number of sensors or ports in parameters\n");
            status = -1;
        }
    
        if (0 == status)
        {
            numSers = 0u;
            //numSensors = 0u;
            i2cAddr = desI2cAddr;
            //cnt < sizeof(UB936_Pattern_cfg)/(sizeof(UB936_Pattern_cfg[0]));
            for (cnt = 0;
                cnt < sizeof(UB936_Normal_cfg)/(sizeof(UB936_Normal_cfg[0]));
                cnt ++)
            {
                regAddr8 = UB936_Normal_cfg[cnt][0] & 0xFF;
                regVal8 = UB936_Normal_cfg[cnt][1] & 0xFF;
                
    	    appLogPrintf (
    		" V3GA Print  Set UB936 register %x: Value:%x\n",
                   	regAddr8, regVal8);
    	
                if ((0x65 == regAddr8) && (numSers < APP_MAX_SENSORS))
                {
                    serI2cAddr[numSers] = regVal8 >> 1u;
                    numSers ++;
                }
    /*
                if ((0x66 == regAddr8) && (numSensors < APP_MAX_SENSORS))
                {
                    sensorI2cAddr[numSensors] = regVal8 >> 1u;
                    numSensors ++;
                }
    */	
                status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                    regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                if (0 != status)
                {
                    appLogPrintf (
                        " REMOTE_SERVICE_SENSOR: Failed to Set UB936 register %x: Value:%x\n",
                        regAddr8, regVal8);
                    break;
                }
                else
                {
                    appLogWaitMsecs(UB936_Normal_cfg[cnt][2]);
                }
            }
        }
            if (0 == status)
            {
                for (cnt1 = 0u; cnt1 < prms->numSensors; cnt1 ++)
                {
                    appLogPrintf(" REMOTE_SERVICE_SENSOR: UB936: Configuring UB913a for sensor %d of %d ... !!!\n", cnt1+1, prms->numSensors);
    
                    i2cAddr = serI2cAddr[cnt1];
                    for (cnt = 0;
                        cnt < sizeof(UB936_UB913a_cfg)/(sizeof(UB936_UB913a_cfg[0]));
                        cnt ++)
                    {
                        regAddr8 = UB936_UB913a_cfg[cnt][0] & 0xFF;
                        regVal8 = UB936_UB913a_cfg[cnt][1] & 0xFF;
    	    	    appLogPrintf (
    			" V3GA Print  Set UB913a register %x: Value:%x\n",
                    	regAddr8, regVal8);
    
                        status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                            regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
                        if (0 != status)
                        {
                           appLogPrintf (
                               " REMOTE_SERVICE_SENSOR: Failed to Set UB913a register %x: Value:%x\n",
                               regAddr8, regVal8);
                           break;
                        }
                        else
                        {
                            appLogWaitMsecs(UB936_UB913a_cfg[cnt][2]);
                        }
                    }
               }
        }
        if (0 == status)
        {
            i2cAddr = desI2cAddr;
            regAddr8 = 0x33;
            regVal8 = 0x3;
            status = Board_i2c8BitRegWr(gI2cHandle, i2cAddr,
                regAddr8, &regVal8, 1, BOARD_I2C_TRANSACTION_TIMEOUT);
            if (0 != status)
            {
               appLogPrintf ("Failed to enable CSI port\n");
            }
    	appLogPrintf("V3GA Print : Enable CSI Port OK, i2cAddr=%d!!! \n", i2cAddr);
        }
    
        if (NULL != gI2cHandle)
        {
            appCloseI2CInst();
        }
    
        return status;
    }
    
    /* ========================================================================== */
    /*                       Static Function Definitions                          */
    /* ========================================================================== */
    
    static int32_t appSetupI2CInst(uint8_t i2cInst)
    {
        int32_t status = 0;
        I2C_Params i2cParams;
    
        /* Initializes the I2C Parameters */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz; /* 400KHz */
    
        /* Configures the I2C instance with the passed parameters*/
        gI2cHandle = I2C_open(i2cInst, &i2cParams);
        if(gI2cHandle == NULL)
        {
            appLogPrintf(" I2C: ERROR: I2C Open Failed!!!\n");
            status = -1;
        }
        return status;
    }
    
    
    static int32_t appCloseI2CInst(void)
    {
        I2C_close(gI2cHandle);
        gI2cHandle = NULL;
    
        return 0;
    }
    
    

    4. capture node param config,

    My app is stopping on vxGraphParameterDequeueDoneRef....

            for(loop_id=0; loop_id<(loop_count+num_buf); loop_id++)
            {
                printf("enter for in loop\n");
                vx_object_array frame;
                /* Get output reference, waits until a frame is available */
                vxGraphParameterDequeueDoneRef(graph, 0, (vx_reference*)&frame, 1, &num_refs);....

             }

    Could you also check if my capture_params is correct for two camera?

    I am thinking it seems that capture node can not receive the camera frame?

    #define NUM_UB962_AR0820_CAPT_CHANNELS      (1u)
    #define NUM_UB962_AR0820_CAPT_INST          (2U)

            capture_params.numInst = NUM_UB962_AR0820_CAPT_INST;  
            capture_params.numCh   =                               
                                    (NUM_UB962_AR0820_CAPT_CHANNELS * NUM_UB962_AR0820_CAPT_INST);
            chIdx = 0U;
            //Jerry test
            for (instIdx = 0U ; instIdx < NUM_UB962_AR0820_CAPT_INST ; instIdx++)
            {
                //capture_params.instId[instIdx] = instIdx;
                capture_params.instId[instIdx] = 1U;
                capture_params.instCfg[instIdx].enableCsiv2p0Support = (uint32_t)vx_true_e;         
                capture_params.instCfg[instIdx].numDataLanes         = 4U;
                for (loop_id = 0U; loop_id < capture_params.instCfg[0U].numDataLanes ; loop_id++)
                {
                    capture_params.instCfg[instIdx].dataLanesMap[loop_id] = (loop_id + 1u);
                }
                for (loop_id = 0U; loop_id < NUM_CAPT_CHANNELS; loop_id++)
                {
                    capture_params.chVcNum[chIdx]   = loop_id;
                    capture_params.chInstMap[chIdx] = instIdx+1;
                    //capture_params.chInstMap[chIdx] = 1U;
                    chIdx++;
                }
            }

    Thanks,

    Jerry Ho

  • 1768.DS90UB962_cfg.h1300.ar0820_linear_config.h

    Hi Brijesh,

    I also put my sensor config and serializer.

    If I only use 1 camera , my code is ok.

    Thanks,

    Jerry Ho

  • Hi Jerry Ho,

    Below code does not seem correct.  I think you are using same CSIRX instance for capturing both the channels of AR820. So the number of instance (numInst) should be 1. Number of channels (numCh) can be 2 as 2 input AR820 camera are connected. 

    #define NUM_UB962_AR0820_CAPT_CHANNELS      (1u)
    #define NUM_UB962_AR0820_CAPT_INST          (2U)

            capture_params.numInst = NUM_UB962_AR0820_CAPT_INST;  
            capture_params.numCh   =                               
                                    (NUM_UB962_AR0820_CAPT_CHANNELS * NUM_UB962_AR0820_CAPT_INST);

    Could you also put breakpoint on the sensor driver and make sure both camera are configured? 

    Regards,

    Brijesh

  • Hi Brijesh,

    1.

    I have tried

    #define NUM_UB962_AR0820_CAPT_CHANNELS      (2u)
    #define NUM_UB962_AR0820_CAPT_INST          (1U)

    The result is still the same ; it is blocked on vxGraphParameterDequeueDoneRef.....

    2.

    Do you mean make sure the 2nd camera 's register is ok?

    Thanks,

    Jerry Ho

  • Hi Brijesh,

    Is it possible to use only the RX1 port camera with connected two AR0820 camera?

    How could I configure the virtual channel id to my capture node?

    Thanks,

    Jerry Ho

  • Hi Jerry,

    How is your connection now? 

    Are you connecting both the AR0820 sensor to single instance of ub960? then it is going to use same CSIRX port. ie CSIRX0.

    Both the channels are identified and separated using virtual channel id and virtual channel id can be specified in chVcNum variable of the capture parameter structure.

    Which application are you using to bringup two channels of AR0820? 

    Can you use multi-camera example? In multi-cam example, you need to select input sensor as A0820 and number of channels as 2. Rest of things are taken care in the example..

    Regards,

    Brijesh

  • Hi Brijesh,

    1. Both the AR0820 sensor are connected with single ub962, and we use CSIRX1.

    2. Could you suggest how to configure chVcNum?

    Currently, my config is

    capture_params.chVcNum[0]= 0, capture_params.chInstMap[0] =1
    capture_params.chVcNum[1]= 1, capture_params.chInstMap[1] =1
    capture_params.chVcNum[2]= 2, capture_params.chInstMap[2] =1
    capture_params.chVcNum[3]= 3, capture_params.chInstMap[3] =1

      

    #define NUM_UB962_AR0820_CAPT_CHANNELS (2u)
    #define NUM_UB962_AR0820_CAPT_INST (1U)

            capture_params.numInst = NUM_UB962_AR0820_CAPT_INST;
            capture_params.numCh   =
                                    (NUM_UB962_AR0820_CAPT_CHANNELS * NUM_UB962_AR0820_CAPT_INST);
            chIdx = 0U;
            //Jerry test
            for (instIdx = 0U ; instIdx < NUM_UB962_AR0820_CAPT_INST ; instIdx++)
            {
                //capture_params.instId[instIdx] = instIdx;
                capture_params.instId[instIdx] = 1U;
                capture_params.instCfg[instIdx].enableCsiv2p0Support = (uint32_t)vx_true_e;
                capture_params.instCfg[instIdx].numDataLanes         = 4U;
                for (loop_id = 0U; loop_id < capture_params.instCfg[0U].numDataLanes ; loop_id++)
                {
                    capture_params.instCfg[instIdx].dataLanesMap[loop_id] = (loop_id + 1u);
                }
                for (loop_id = 0U; loop_id < NUM_CAPT_CHANNELS; loop_id++)
                {
                    capture_params.chVcNum[chIdx]   = loop_id;
                    //capture_params.chInstMap[chIdx] = instIdx+1;
                    capture_params.chInstMap[chIdx] = 1U;
                    chIdx++;
                }
            }

    3. I am using the test_capture_display from my colleague , and it 's ok for only one camera on RX port 0.

    so I am trying to add other AR0820 on RX port 1.

    I will try multi-cam example , if the test_capture_display is ok.

    Thanks,

    Jerry Ho

  • Hi Jerry,

    ok, above changes look fine. 

    Do you use UB962_Normal_with_AR0820_cfg to configure ub962?

    Also what is the output resolution from AR0820? Are you using 3840x2160 resolution? Do you see any overflow in the CSIRX? 

    Regards,

    Brijesh

  • Hi Brijesh,

    1.Yes I use UB962_Normal_with_AR0820_cfg.

    It's fine with single RX0 AR0820.

    2.Yes , I use 3840x2160 currently.

    3. No, I don't see any error message.

        Do I need to enable debug level of messages?

    Thanks,

    Jerry Ho

  • Hi Brijesh,

    capture_params.chVcNum[0]= 0,

    capture_params.chVcNum[1]= 1

    Do these chVcNum[0] and params.chVcNum[1] mean the virutual channel ID for my two AR0820 camera?

    Could I only assign only RX1 camera output to my display LCD ?

    Thanks,

    Jerry Ho

  • Hi Jerry,

    No not the error message, but there is an overflow flag/interrupt. We need to check if it is getting set. Let me check and share it.

    Yes, chVcNum means virtual channel id.

    In the test_capture_display, only one of the camera is connected to the display. 

    But i guess you are not even seeing single camera output, isn't it?

    Regards,

    Brijesh

  • Hi Brijesh,

    In the test_capture_display, only one of the camera is connected to the display. 

    But i guess you are not even seeing single camera output, isn't it?

    >>

    How could I only select the rx1 camera to my display if only connect rx1 camera?

    No,if two camera is connected,no any display to lcd, it blocks on dequeue...

    Thanks,

    Jerry Ho

  • Hi Jerry,

    Can you please read the value of register CSI_RX_IF_VBUS2APB_ERROR_IRQS (0x04504028), while running the usecase?

    Regards,

    Brijesh

  • and also value at offset 0x04514028 ?

  • Hi Brijesh,

    Could you procvide how could I read these two offet set?

    Thanks,

    Jerry Ho

  • Hi Jerry,

    You could connect to main domain R5F using CCS and JTAG and can read these two registers. 

    or you could use k3conf Linux utility to read these registers.

    Regards,

    Brijesh

  • Hi Brijesh,

    Could you give more detail for getting these registers?

    like

    k3conf read 0x04504028 ?

    and

    k3conf read 0x04514028 ?

    Thanks,

    Jerry Ho

  • Hi Brijesh,

    Could you explain this setting from this picture?

    why if using RX0,  this value is 0x00?

    and

    why if using RX1,  this value is 0x55?

    If I would like to use only one RX1 port (AR0820) not connecting RX0 physically , how could I config this register 0x72 and chVcNum?

    Thanks,
    Jerry Ho

  • Hi Jerry,

    Yes, that is correct way to read these two registers. Can you read them and share the values? 

    The VC_MAP register is use to map to different VC number from input vc number. Lets say if your input VC number is 3, but you want to send it as 0, you could do it using this register. 

    In our configuration, we configure to map all (any) input VC number to fixed single VC for that input channel. For example, value 0x55 means any input VC number will be mapped to VC number 0x1.

    Regards,

    Brijesh

  • Hi Brijesh,

    these two values are 0.

    root@j7-evm:~# k3conf read 0x04504028
    |--------------------------------------------------------------------------------|
    | VERSION INFO                                                                   |
    |--------------------------------------------------------------------------------|
    | K3CONF | (version v0.1-34-g1ff0c4f built Wed Apr 21 22:45:10 UTC 2021)         |
    | SoC    | J721E SR1.0                                                           |
    | SYSFW  | ABI: 3.1 (firmware version 0x0014 '20.8.5--v2020.08b (Terrific Lla)') |
    |--------------------------------------------------------------------------------|

    Value at addr 0x4504028 = 0x0

    root@j7-evm:~# k3conf read 0x04514028
    |--------------------------------------------------------------------------------|
    | VERSION INFO                                                                   |
    |--------------------------------------------------------------------------------|
    | K3CONF | (version v0.1-34-g1ff0c4f built Wed Apr 21 22:45:10 UTC 2021)         |
    | SoC    | J721E SR1.0                                                           |
    | SYSFW  | ABI: 3.1 (firmware version 0x0014 '20.8.5--v2020.08b (Terrific Lla)') |
    |--------------------------------------------------------------------------------|

    Value at addr 0x4514028 = 0x0

    Thanks,

    Jerry Ho

  • Hi Brijesh,

    I can't still understand the VC-ID concept.

    For RX1 AR0820 camera, does this camera only use VC-ID of 1(bit2-3) part?

    why do I need still config bit(0-1) and bit(4-7)?

    does one camera use VC-ID bit(0-1) and bit(4-7) ? if Yes, why?

    Thanks,

    Jerry Ho

  • Hi Jerry,

    Have you captured these values when the usecase is running? if not, can you capture it?

    It is just the mapping. If the input from camera is on VC Id 0, you could still output on CSI2 from Deserializer on VC Id, lets say, 3. This is possible using this VC map register. Please refer to ub962  specs for more information. 

    Regards,

    Brijesh

  • Hi Brijesh,

    1. Do you mean capture these two value when my one camera AR0820 is active?

    Thanks,

    Jerry Ho

  • No when both the camera are active and enabled..

  • Yes, I use a ssh connection and get this two value when I test two AR0820 at the same time.

  • Hi Brijesh,

    This bug still exists, but I don't know why this issue is labeled resolved..

    Could you keep support it?

    Thanks,

    Jerry Ho

  • Hi Jerry,

    Sure, I am opening this thread.

    Regards,

    Brijesh

  • Hi Jerry,

    Lets continue our discussion on the other thread.

    I am closing this thread.

    Regards,

    Brijesh