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.

CCS/TDA4VM: [ UB960-Q1 - UB913A ] Device driver Create

Part Number: TDA4VM

Tool/software: Code Composer Studio

Hello Expert,

This thread moved from compiler forum. (https://e2e.ti.com/support/interface/f/138/p/923370/3413668#3413668)


I am currently writing device driver code for UB913A-Q1 and UB960.


I created the device driver by referring to the previous device driver code.

Now, i can see my device driver in 'app_single_cam_main.c'

But, this device driver does not seem to work properly.

I want to save the image to test my camera, but nothing is saved.

It seems that I am modifying serDes or app_single_cam_main.c incorrectly.


I will share my current situation, can you please confirm?

-------------------------------------------------------------------------

Deserializer register config

{0x4C, 0x01,0x10},
{0x58, 0x58,0x10},
{0xD5, 0xF0,0x10},
{0x6D, 0x6F,0x10}, /*raw 10 mode*/
{0x70, 0x1E,0x10},

{0x5D, (BSPUTILS_SER_ID_ADDR << 1U), 0x10}, /*Serializer I2C Address*/
{0x65, (SER_0_I2C_ALIAS << 1U), 0x10},
{0x5E, ISX016_I2C_ADDR, 0x10}, /*Sensor I2C Address*/
{0x66, (SENSOR_0_I2C_ALIAS << 1U), 0x10},
{0x32, 0x01,0x0},

{0x20, 0x00, 0x10},
{0x21, 0x03, 0x0},

{0xFFFF, 0x00, 0x0} //End of script

app_single_cam_main.c

VISS and 2A nodes are removed from the graph

And i set,

capture_node => obj->mydata => display_image


And image dump,

write_output_image_raw(raw_image_fname, obj->mydata);


The data type of obj->mydata is vx_image.

---------------------------------------------------------------------

Do you have any idea where I'm setting it wrong?

Any advice is appreciated.

Regards,

Kim

  • Are you able to get the lock between deserializer and serializer?

    is the sensor and serilaizer I2C access working?

  • Hello, Mayank

    Thanks your reply.

    what is 'get the lock between deserializer and serializer?'


    please, could explain it in more detail.


    The sensor and serilaizer I2C access seems to work, but is there a way to make sure?

    Can you tell me know?


    I look forward to your reply.

    Regards,

    Kim

  • lock is needed for the serializer and deserializer to establish backchannel communication. There is a deserializer register to indicate lock status. You can find it in UB960 datasheet.

    If sensor/serializer comunication is working it means lock has been established. You can verify by reading sensor chip id register.

  • Hello, Mayank

    I have two questions.

    1. Is this the LOCK you said is correct?


    2. Can you tell me how to read I2C Register value from TDA4?

    I tried to find a way to read the register to check the register value I set, but I couldn't find it.

    Regards,

    Kim

  • Yes that's the correct register. You can use the API Board_i2c8BitRegRd to read from UB960.

  • Hello Mayank,


    I will answer it after test.

    Please do not close the thread until then.

    Thank you.

    Kim

  • Hello Mayank,

    It's a little different way, I checked the value after setting the register in U-boot.


    Register 0x4d LOCK status was active( it means register value is 1).


    Also, the register value of the serializer could be read through the Alias ​​ID.


    Currently, My Deserializer's register value is changed. a little.

        {0x4C, 0x01,0x10},
        {0x58, 0x58,0x10},
        {0xD5, 0xF0,0x10},
        {0x6D, 0x6F,0x10},
        {0x70, 0x1F,0x10},

        //{0x5B, (BSPUTILS_SER_ID_ADDR << 1U), 0x10}, 
        {0x5C, (SER_0_I2C_ALIAS << 1U), 0x10},   //E8(8bit)      => 74 (7bit)
        {0x5D, ISX016_I2C_ADDR<<1U, 0x10},       //34(8bit)     => 1A (7bit)
        {0x65, (SENSOR_0_I2C_ALIAS << 1U), 0x10},//80(8bit)     => 40 (7bit)
        {0x32, 0x01,0x0},

        {0x20, 0x00, 0x10},
        {0x21, 0x03, 0x0},

        {0xFFFF, 0x00, 0x0} //End of script
    -----------------------------------------------------------------

    The register values ​​for the Alias ​​ID of the serializer and Image sensor ID have changed.
    But, No data is still stored.


    Please, Any advice.

    Thanks you,

    Kim

  • Kim,

    Are you able to confirm that the sensor and UB960 are sending the data to TDA4? There are a few things you should check

    1. MIPI configuration (number of lanes etc) matches on Rx and Tx side

    2. There is valid clock and data signal on TDA4 CSI pins

    Regards,

    Mayank

  • Hello Mayank,


    The serializer is DS90UB913A.


    I know that this serializer works in RAW MODE, not CSI MODE.


    So I didn't understand to check the data signal of TDA4 CSI pin.

    For reference, I applied the valid clock for UB913 by referring to the datasheet.


    Is that what I know? Please tell me if it is wrong.


    In addition, The current display dp is also not displayed.

    My SDK version is 07_00_00_00.

    Is there a problem with the hwa kernel in charge of capture and display?


    Sorry for being slightly off the thread.

    Regards,

    Kim

  • Hello Kim,

    UB960 has only a CSI output which it uses to send video data to TDA4. Therefore, I request you to check if the data and clock signals are being received at TDA4 pins.

    I would request you to create a new E2E thread for display questions.

    Regards,

    Mayank

  • Hello Mayank,

    Thanks for the advice.


    Currently, I checked just two.

    number of lanes : 4
    back channel Freq : 2.5 Mbps

    I'm going to attach the my saved image (but it was only noise.)

    What you said, Is it check to hardware?

    Could you please let me know,
    if there is a way to check it in software?

    Regards,

    Kim

  • Kim,

    Please verify that MIPI clock and data signals are reaching TDA4 pins. I am not aware of a foolproof way of checking that in SW. I would recommend doing that on the HW.

    Regards,

    Mayank

  • Hello Mayank,

    In the current situation, I'm going to proceed with the project on the assumption that there is no problem between TDA4 and UB960.

    Currently, what I have confirmed is that vxGraphParameterDequeueDoneRef in app_single_cam_main.c waits indefinitely.

    I think, It is because of the Deque that nothing is stored in the image file.


    I changed node configuration as below.

    It change from  to capture->viss->dss to capture-->dss. (viss remove. Because I use UB913 Serializer)


    Looking at the release note of vision_apps,

    it was confirmed that data should be transmitted to the 'ALG AEWB' and transmitted to the sensor driver.

    is right?


    Do I need to send data to 'ALG AEWB' and sensor driver even when viss is deleted?


    If it's wrong, could you tell me why deque is not working?

    Thanks for all advice.


    Attach my app_single_cam code, log and SerDes Config file.

    root@j7-evm:/opt/vision_apps# ./run_app_single_cam.sh
    APP: Init ... !!!
    MEM: Init ... !!!
    MEM: Initialized DMA HEAP (fd=4) !!!
    MEM: Init ... Done !!!
    IPC: Init ... !!!
    IPC: Init ... Done !!!
    REMOTE_SERVICE: Init ... !!!
    REMOTE_SERVICE: Init ... Done !!!
    APP: Init ... Done !!!
        59.975282 s:  VX_ZONE_INIT:Enabled
        59.975293 s:  VX_ZONE_ERROR:Enabled
        59.975298 s:  VX_ZONE_WARNING:Enabled
        59.975848 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
        59.975998 s:  VX_ZONE_INIT:[tivxHostInit:48] Initialization Done for HOST !!!
    sensor_selection = [0]
    ldc_enable = [0]
    num_frames_to_run = [1000000000]
    is_interactive = [1]
    IttCtrl_registerHandler: command echo registered at location 0
    IttCtrl_registerHandler: command iss_read_2a_params registered at location 1
    IttCtrl_registerHandler: command iss_write_2a_params registered at location 2
    IttCtrl_registerHandler: command iss_raw_save registered at location 3
    IttCtrl_registerHandler: command iss_yuv_save registered at location 4
    IttCtrl_registerHandler: command iss_read_sensor_reg registered at location 5
    IttCtrl_registerHandler: command iss_write_sensor_reg registered at location 6
    IttCtrl_registerHandler: command dev_ctrl registered at location 7
    IttCtrl_registerHandler: command iss_send_dcc_file registered at location 8
        59.978350 s: ISS: Enumerating sensors ... !!!
     NETWORK: Opened at IP Addr = 0.0.0.0, socket port=5000!!!
        59.978726 s: ISS: Enumerating sensors ... found 0 : IMX390-UB953_D3
        59.978733 s: ISS: Enumerating sensors ... found 1 : AR0233-UB953_MARS
        59.978738 s: ISS: Enumerating sensors ... found 2 : AR0820-UB953_LI
        59.978742 s: ISS: Enumerating sensors ... found 3 : UB9702_TESTPATTERN
        59.978746 s: ISS: Enumerating sensors ... found 4 : ISX016-UB913
    5 sensor(s) found
    Supported sensor list:
    a : IMX390-UB953_D3
    b : AR0233-UB953_MARS
    c : AR0820-UB953_LI
    d : UB9702_TESTPATTERN
    e : ISX016-UB913
    Select a sensor
    [MCU2_0]     59.978455 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_CREATE
    [MCU2_0]     59.978525 s: Sensor at index 0 = IMX390-UB953_D3
    [MCU2_0]     59.978558 s: Sensor at index 1 = AR0233-UB953_MARS
    [MCU2_0]     59.978583 s: Sensor at index 2 = AR0820-UB953_LI
    [MCU2_0]     59.978619 s: Sensor at index 3 = UB9702_TESTPATTERN
    [MCU2_0]     59.978647 s: Sensor at index 4 = ISX016-UB913
    e
    
    LDC Selection Yes(1)/No(0)
    LDC Selection Yes(1)/No(0)
    1
    Sensor selected : ISX016-UB913
    Querying ISX016-UB913
        61.290370 s: ISS: Querying sensor [ISX016-UB913] ... !!!
        61.290627 s: ISS: Querying sensor [ISX016-UB913] ... Done !!!
        61.290633 s: ISS: Initializing sensor [ISX016-UB913], doing IM_SENSOR_CMD_PWRON ... !!!
    [MCU2_0]     61.290452 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_QUERY
    [MCU2_0]     61.290520 s: Received Query for ISX016-UB913
    [MCU2_0]     61.290707 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_PWRON
    [MCU2_0]     61.290799 s: IM_SENSOR_CMD_PWRON : channel_mask = 0x1
    [MCU2_0]     61.290928 s: ISX016_PowerOn : chMask = 0x1
    [MCU2_0]     61.290971 s: ub960_cfgScript : ub960I2cAddr = 0x3d
    [MCU2_0]     61.291034 s: UB960 config start
    [MCU2_0]     61.291168 s: 0x4c = 0x1
    [MCU2_0]     61.307119 s: 0x58 = 0x58
    [MCU2_0]     61.323110 s: 0xd5 = 0xf0
    [MCU2_0]     61.339116 s: 0x6d = 0x6f
    [MCU2_0]     61.355122 s: 0x70 = 0x1f
    [MCU2_0]     61.371111 s: 0x5c = 0xe8
    [MCU2_0]     61.387120 s: 0x5d = 0x34
    [MCU2_0]     61.403116 s: 0x65 = 0x80
    [MCU2_0]     61.403254 s: 0x32 = 0x1
    [MCU2_0]     61.419120 s: 0x20 = 0x0
    [MCU2_0]     61.419253 s: 0x21 = 0x3
    [MCU2_0]     61.419283 s: --------Reg check Start-----------
    [MCU2_0]     61.421355 s: regAddr = 00 | 7a -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     61.423398 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     61.425464 s: regAddr = 20 | -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.427499 s: regAddr = 30 | -- -- 01 -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.429568 s: regAddr = 40 | -- a9 71 01 -- -- 20 20 -- -- -- 12 01 33 cd 25
    [MCU2_0]     61.431631 s: regAddr = 50 | 20 -- -- -- -- -- -- -- 58 -- -- b0 e8 34 -- --
    [MCU2_0]     61.433692 s: regAddr = 60 | -- -- -- -- -- 80 -- -- -- -- -- -- -- 6f 88 88
    [MCU2_0]     61.435767 s: regAddr = 70 | 1f 2c e4 02 d0 0c 80 c5 -- 01 0f ff 20 -- -- --
    [MCU2_0]     61.437799 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.439854 s: regAddr = 90 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.441894 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
        61.452371 s: ISS: Initializing sensor [ISX016-UB913], doing IM_SENSOR_CMD_CONFIG ... !!!
    [MCU2_0]     61.443961 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- fc 33 83 74 80 -- -- --
    [MCU2_0]     61.446003 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.448067 s: regAddr = d0 | -- 43 94 05 60 f0 -- 02 -- -- -- -- -- -- -- --
    [MCU2_0]     61.450116 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.452184 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.452242 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     61.452268 s:  End of UB960 config
    [MCU2_0]     61.452296 s: Can't Power On -----chMask = 0x1
    [MCU2_0]     61.452442 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_CONFIG
    [MCU2_0]     61.452484 s: Application requested features = 0x358
    [MCU2_0]
    [MCU2_0]     61.452528 s: ---------disable
    [MCU2_0]     61.452571 s: ub960_cfgScript : ub960I2cAddr = 0x3d
    [MCU2_0]     61.452595 s: UB960 config start
    [MCU2_0]     61.452714 s: 0x4c = 0x0
    [MCU2_0]     61.468116 s: 0x5c = 0xe8
    [MCU2_0]     61.484124 s: 0x65 = 0x80
    [MCU2_0]     61.500114 s: 0x72 = 0x0
    [MCU2_0]     61.516112 s: 0x4c = 0x0
    [MCU2_0]     61.532111 s: 0x5c = 0xec
    [MCU2_0]     61.548114 s: 0x65 = 0x84
    [MCU2_0]     61.564113 s: 0x72 = 0x55
    [MCU2_0]     61.580125 s: 0x4c = 0x0
    [MCU2_0]     61.596114 s: 0x5c = 0xf0
    [MCU2_0]     61.612126 s: 0x65 = 0x88
    [MCU2_0]     61.628108 s: 0x72 = 0xaa
    [MCU2_0]     61.644111 s: 0x4c = 0x0
    [MCU2_0]     61.660114 s: 0x5c = 0xf4
    [MCU2_0]     61.676126 s: 0x65 = 0x8c
    [MCU2_0]     61.692124 s: 0x72 = 0xff
    [MCU2_0]     61.692170 s: --------Reg check Start-----------
    [MCU2_0]     61.694281 s: regAddr = 00 | 7a -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     61.696324 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     61.698373 s: regAddr = 20 | -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.700425 s: regAddr = 30 | -- -- 01 -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.702508 s: regAddr = 40 | -- a9 71 01 -- -- 20 -- -- -- -- 12 -- 03 04 25
    [MCU2_0]     61.704567 s: regAddr = 50 | 20 -- -- -- -- -- -- -- 58 -- -- b0 e8 34 -- --
    [MCU2_0]     61.706627 s: regAddr = 60 | -- -- -- -- -- 80 -- -- -- -- -- -- -- 6f 88 88
    [MCU2_0]     61.708719 s: regAddr = 70 | 1f 2c e4 02 d0 0c 80 c5 -- 01 -- -- 20 -- -- --
    [MCU2_0]     61.710748 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.712801 s: regAddr = 90 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.714856 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.716912 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- fc 33 83 74 80 -- -- --
    [MCU2_0]     61.718940 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.721004 s: regAddr = d0 | -- 43 94 05 60 f0 -- 02 -- -- -- -- -- -- -- --
    [MCU2_0]     61.723057 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.725129 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.725188 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     61.725216 s:  End of UB960 config
    [MCU2_0]     61.725251 s: ub960_cfgScript : ub960I2cAddr = 0x36
    [MCU2_0]     61.725275 s: UB960 config start
    [MCU2_0]     61.725391 s: 0x4c = 0x0
    [MCU2_0]     61.741113 s: 0x5c = 0xd8
    [MCU2_0]     61.757114 s: 0x65 = 0x90
    [MCU2_0]     61.773125 s: 0x72 = 0x0
    [MCU2_0]     61.789121 s: 0x4c = 0x0
    [MCU2_0]     61.805124 s: 0x5c = 0xdc
    [MCU2_0]     61.821111 s: 0x65 = 0x94
    [MCU2_0]     61.837112 s: 0x72 = 0x55
    [MCU2_0]     61.853110 s: 0x4c = 0x0
    [MCU2_0]     61.869110 s: 0x5c = 0xe0
    [MCU2_0]     61.885124 s: 0x65 = 0x98
    [MCU2_0]     61.901116 s: 0x72 = 0xaa
    [MCU2_0]     61.917111 s: 0x4c = 0x0
    [MCU2_0]     61.933109 s: 0x5c = 0xe4
    [MCU2_0]     61.949111 s: 0x65 = 0x9c
    [MCU2_0]     61.965124 s: 0x72 = 0xff
    [MCU2_0]     61.965167 s: --------Reg check Start-----------
    [MCU2_0]     61.967222 s: regAddr = 00 | 6c -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     61.969261 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     61.971313 s: regAddr = 20 | f0 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.973364 s: regAddr = 30 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.975469 s: regAddr = 40 | -- a9 71 01 -- -- 20 -- -- -- -- 12 -- -- 02 --
    [MCU2_0]     61.977525 s: regAddr = 50 | -- -- -- -- -- -- -- -- 1e -- -- -- -- -- -- --
    [MCU2_0]     61.979569 s: regAddr = 60 | -- -- -- -- -- -- -- -- -- -- -- -- -- 7c 88 88
    [MCU2_0]     61.981635 s: regAddr = 70 | 2b 2c e4 -- -- -- -- c5 -- 01 -- -- 20 -- -- --
    [MCU2_0]     61.983678 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.985731 s: regAddr = 90 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.987771 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.989839 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- bc 33 83 74 80 -- -- --
    [MCU2_0]     61.991879 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.993943 s: regAddr = d0 | -- 43 94 07 60 f2 -- 03 -- -- -- -- -- -- -- --
    [MCU2_0]     61.995993 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.998058 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     61.998115 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     61.998144 s:  End of UB960 config
    [MCU2_0]     61.998163 s: Configuring camera # 0
    [MCU2_0]     61.998192 s: ub913 config start : slaveAddr = 0x74
    [MCU2_0]     61.998216 s: ub913 config start : i2cInstId = 0x6
    [MCU2_0]     61.998389 s: ISX016 Config0x1 = 0x30
    [MCU2_0]     62.014177 s: 0x3 = 0xc5
    [MCU2_0]     62.030161 s: 0xd = 0x55
    [MCU2_0]     62.046153 s: 0x5 = 0x15
    [MCU2_0]     62.062150 s: 0x11 = 0x32
        62.078326 s: ISS: Initializing sensor [ISX016-UB913] ... Done !!!
    [MCU2_0]     62.078181 s: 0x12 = 0x32
    [MCU2_0]     62.078221 s:  End of UB913 config
    [MCU2_0]     62.078248 s: IM_SENSOR_CMD_CONFIG returning status = 0
    Scaler is disabled
    
    
     ==========================
     Demo : Single Camera w/ 2A
     ==========================
    
     p: Print performance statistics
    
     s: Save Sensor RAW, VISS Output and H3A output images to File System
    
     e: Export performance statistics
    
     x: Exit
    
     Enter Choice:
    
    
     ==========================
     Demo : Single Camera w/ 2A
     ==========================
    
     p: Print performance statistics
    
     s: Save Sensor RAW, VISS Output and H3A output images to File System
    
     e: Export performance statistics
    
     x: Exit
    
     Enter Choice:     62.129875 s: ISS: Starting sensor [ISX016-UB913] ... !!!
    [MCU2_0]     62.130016 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON
    [MCU2_0]     62.130089 s: IM_SENSOR_CMD_STREAM_ON:  channel_mask = 0x1
    [MCU2_0]     62.130152 s: ub960_cfgScript : ub960I2cAddr = 0x3d
    [MCU2_0]     62.130198 s: UB960 config start
    [MCU2_0]     62.130330 s: 0x4c = 0x0
    [MCU2_0]     62.146116 s: 0x5c = 0xe8
    [MCU2_0]     62.162115 s: 0x65 = 0x80
    [MCU2_0]     62.178142 s: 0x72 = 0x0
    [MCU2_0]     62.194113 s: 0x4c = 0x0
    [MCU2_0]     62.210113 s: 0x5c = 0xec
    [MCU2_0]     62.226114 s: 0x65 = 0x84
    [MCU2_0]     62.242126 s: 0x72 = 0x55
    [MCU2_0]     62.258113 s: 0x4c = 0x0
    [MCU2_0]     62.274114 s: 0x5c = 0xf0
    [MCU2_0]     62.290120 s: 0x65 = 0x88
    [MCU2_0]     62.306113 s: 0x72 = 0xaa
    [MCU2_0]     62.322115 s: 0x4c = 0x0
    [MCU2_0]     62.338111 s: 0x5c = 0xf4
    [MCU2_0]     62.354107 s: 0x65 = 0x8c
    [MCU2_0]     62.370117 s: 0x72 = 0xff
    [MCU2_0]     62.370161 s: --------Reg check Start-----------
    [MCU2_0]     62.372230 s: regAddr = 00 | 7a -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     62.374305 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     62.376375 s: regAddr = 20 | -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.378434 s: regAddr = 30 | -- -- 01 -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.380514 s: regAddr = 40 | -- a9 71 01 -- -- 20 -- -- -- -- 12 -- 03 04 25
    [MCU2_0]     62.382568 s: regAddr = 50 | 20 -- -- -- -- -- -- -- 58 -- -- b0 e8 34 -- --
    [MCU2_0]     62.384621 s: regAddr = 60 | -- -- -- -- -- 80 -- -- -- -- -- -- -- 6f 88 88
    [MCU2_0]     62.386693 s: regAddr = 70 | 1f 2c e4 02 d0 0c 80 c5 -- 01 -- -- 20 -- -- --
    [MCU2_0]     62.388736 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.390778 s: regAddr = 90 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.392822 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.394883 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- fc 33 83 74 80 -- -- --
    [MCU2_0]     62.396923 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.398987 s: regAddr = d0 | -- 43 94 05 60 f0 -- 02 -- -- -- -- -- -- -- --
    [MCU2_0]     62.401016 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.403062 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.403119 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     62.403147 s:  End of UB960 config
    [MCU2_0]     62.403182 s: ub960_cfgScript : ub960I2cAddr = 0x36
    [MCU2_0]     62.403204 s: UB960 config start
    [MCU2_0]     62.403320 s: 0x4c = 0x0
    [MCU2_0]     62.419122 s: 0x5c = 0xd8
    [MCU2_0]     62.435114 s: 0x65 = 0x90
    [MCU2_0]     62.451117 s: 0x72 = 0x0
    [MCU2_0]     62.467111 s: 0x4c = 0x0
    [MCU2_0]     62.483122 s: 0x5c = 0xdc
    [MCU2_0]     62.499116 s: 0x65 = 0x94
    [MCU2_0]     62.515119 s: 0x72 = 0x55
    [MCU2_0]     62.531109 s: 0x4c = 0x0
    [MCU2_0]     62.547111 s: 0x5c = 0xe0
    [MCU2_0]     62.563108 s: 0x65 = 0x98
    [MCU2_0]     62.579123 s: 0x72 = 0xaa
    [MCU2_0]     62.595113 s: 0x4c = 0x0
    [MCU2_0]     62.611115 s: 0x5c = 0xe4
    [MCU2_0]     62.627114 s: 0x65 = 0x9c
    [MCU2_0]     62.643119 s: 0x72 = 0xff
    [MCU2_0]     62.643177 s: --------Reg check Start-----------
    [MCU2_0]     62.645273 s: regAddr = 00 | 6c -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     62.647318 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     62.649372 s: regAddr = 20 | f0 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.651424 s: regAddr = 30 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.653493 s: regAddr = 40 | -- a9 71 01 -- -- 20 -- -- -- -- 12 -- -- 02 --
    [MCU2_0]     62.655525 s: regAddr = 50 | -- -- -- -- -- -- -- -- 1e -- -- -- -- -- -- --
    [MCU2_0]     62.657582 s: regAddr = 60 | -- -- -- -- -- -- -- -- -- -- -- -- -- 7c 88 88
    [MCU2_0]     62.659641 s: regAddr = 70 | 2b 2c e4 -- -- -- -- c5 -- 01 -- -- 20 -- -- --
    [MCU2_0]     62.661676 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.663728 s: regAddr = 90 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.665769 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.667827 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- bc 33 83 74 80 -- -- --
    [MCU2_0]     62.669865 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.671927 s: regAddr = d0 | -- 43 94 3f 60 f2 -- 03 -- -- -- -- -- -- -- --
    [MCU2_0]     62.673993 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.676064 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.676120 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     62.676147 s:  End of UB960 config
    [MCU2_0]     62.676168 s: Starting camera # 0
    [MCU2_0]     62.676194 s: Entering IssSensor_Start
    [MCU2_0]     62.676221 s: Stream start
    [MCU2_0]     62.686033 s: enableUB960Streaming ub960InstanceId = 0
    [MCU2_0]     62.686235 s: ub960_cfgScript : ub960I2cAddr = 0x3d
    [MCU2_0]     62.686264 s: UB960 config start
    [MCU2_0]     62.686381 s: 0x4c = 0x1
    [MCU2_0]     62.702114 s: 0x33 = 0x3
    [MCU2_0]     62.702160 s: --------Reg check Start-----------
    [MCU2_0]     62.704249 s: regAddr = 00 | 7a -- 1e 40 d0 01 -- fe 1c 10 7a 7a 0f b9 10 ff
    [MCU2_0]     62.706307 s: regAddr = 10 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- 04 02
    [MCU2_0]     62.708374 s: regAddr = 20 | -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.710434 s: regAddr = 30 | -- -- 01 03 -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.712517 s: regAddr = 40 | -- a9 71 01 -- -- 20 -- -- -- -- 12 01 03 04 25
    [MCU2_0]     62.714567 s: regAddr = 50 | 20 -- -- -- -- -- -- -- 58 -- -- b0 e8 34 -- --
    [MCU2_0]     62.716637 s: regAddr = 60 | -- -- -- -- -- 80 -- -- -- -- -- -- -- 6f 88 88
    [MCU2_0]     62.718691 s: regAddr = 70 | 1f 2c e4 02 d0 0c 80 c5 -- 01 -- -- 20 -- -- --
    [MCU2_0]     62.720742 s: regAddr = 80 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.722804 s: regAddr = 90 | -- 01 -- -- ff ff ff ff -- -- -- -- -- -- -- --
    [MCU2_0]     62.724879 s: regAddr = a0 | -- -- -- -- -- 1a -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.726956 s: regAddr = b0 | 1c 3a 14 08 25 -- 18 -- fc 33 83 74 80 -- -- --
    [MCU2_0]     62.729001 s: regAddr = c0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.731063 s: regAddr = d0 | -- 43 94 05 60 f0 -- 02 -- -- -- -- -- -- -- --
    [MCU2_0]     62.733088 s: regAddr = e0 | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        62.735298 s: ISS: Starting sensor [ISX016-UB913] ... !!!
    enque deque
    appPerfPointBegin
    [MCU2_0]     62.735130 s: regAddr = f0 | 5f 55 42 39 36 30 -- -- -- -- -- -- -- -- -- --
    [MCU2_0]     62.735186 s: regAddr = 100 | --------Reg check Done-----------
    [MCU2_0]     62.735215 s:  End of UB960 config
    
    
    
    
     ==========================
     Demo : Single Camera w/ 2A
     ==========================
    
     p: Print performance statistics
    
     s: Save Sensor RAW, VISS Output and H3A output images to File System
    
     e: Export performance statistics
    
     x: Exit
    

    /*
     *
     * Copyright (c) 2018 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 "app_single_cam_main.h"
    #include <utils/iss/include/app_iss.h>
    
    #ifdef A72
    #if defined(LINUX)
    /*ITT server is supported only in target mode and only on Linux*/
    #include <itt_server.h>
    #endif
    #endif
    
    #include "ldc_lut_1920x1080.h"
    
    static char availableSensorNames[ISS_SENSORS_MAX_SUPPORTED_SENSOR][ISS_SENSORS_MAX_NAME];
    static vx_uint8 num_sensors_found;
    static IssSensor_CreateParams sensorParams;
    
    static uint8_t  ldc_lut[] = LDC_LUT_1920_1080;
    
    #define LDC_TABLE_WIDTH             (1920)
    #define LDC_TABLE_HEIGHT            (1080)
    #define LDC_DS_FACTOR               (2)
    #define LDC_BLOCK_WIDTH             (64)
    #define LDC_BLOCK_HEIGHT            (32)
    #define LDC_PIXEL_PAD               (1)
    
    #define CAPT_INST_ID                (0U)
    
    char *app_get_test_file_path()
    {
        char *tivxPlatformGetEnv(char *env_var);
    
        #if defined(SYSBIOS)
        return tivxPlatformGetEnv("VX_TEST_DATA_PATH");
        #else
        return getenv("VX_TEST_DATA_PATH");
        #endif
    }
    
    
    /*
     * Utility API used to add a graph parameter from a node, node parameter index
     */
    void add_graph_parameter_by_node_index(vx_graph graph, vx_node node, vx_uint32 node_parameter_index)
    {
        vx_parameter parameter = vxGetParameterByIndex(node, node_parameter_index);
    
        vxAddParameterToGraph(graph, parameter);
        vxReleaseParameter(&parameter);
    }
    
    vx_status app_init(AppObj *obj)
    {
        vx_status status = VX_FAILURE;
        char* sensor_list[ISS_SENSORS_MAX_SUPPORTED_SENSOR];
        vx_uint8 count = 0;
        char ch = 0xFF;
        vx_uint8 selectedSensor = 0xFF;
    
    #ifdef A72
    #if defined(LINUX)
    /*ITT server is supported only in target mode and only on Linux*/
        status = itt_server_init((void*)obj, (void*)save_debug_images);
        if(status != 0)
        {
            printf("Warning : Failed to initialize ITT server. Live tuning will not work \n");
        }
    #endif
    #endif
    
        obj->stop_task = 0;
        obj->stop_task_done = 0;
    
        obj->context = vxCreateContext();
        APP_ASSERT_VALID_REF(obj->context);
    
        tivxHwaLoadKernels(obj->context);
        tivxImagingLoadKernels(obj->context);
        APP_PRINTF("tivxImagingLoadKernels done\n");
    
        memset(availableSensorNames, 0, ISS_SENSORS_MAX_SUPPORTED_SENSOR*ISS_SENSORS_MAX_NAME);
        for(count=0;count<ISS_SENSORS_MAX_SUPPORTED_SENSOR;count++)
        {
            sensor_list[count] = availableSensorNames[count];
        }
        status = appEnumerateImageSensor(sensor_list, &num_sensors_found);
        if(VX_SUCCESS != status)
        {
            printf("appCreateImageSensor returned %d\n", status);
            return status;
        }
    
           if(obj->is_interactive)
           {
            while(selectedSensor > (num_sensors_found-1))
            {
                printf("%d sensor(s) found \n", num_sensors_found);
                printf("Supported sensor list: \n");
                for(count=0;count<num_sensors_found;count++)
                {
                   printf("%c : %s \n", count+'a', sensor_list[count]);
                }
    
                printf("Select a sensor \n");
                ch = getchar();
                printf("\n");
                selectedSensor = ch - 'a';
                if(selectedSensor > (num_sensors_found-1))
                {
                    printf("Invalid selection %c. Try again \n", ch);
                }
            }
    
            while ((ch != '0') && (ch != '1'))
            {
                fflush (stdin);
                printf ("LDC Selection Yes(1)/No(0)\n");
                ch = getchar();
            }
    
            obj->ldc_enable = ch - '0';
           }
        else
        {
            selectedSensor = obj->sensor_sel;
            if(selectedSensor > (num_sensors_found-1))
            {
                printf("Invalid sensor selection %d \n", selectedSensor);
                return VX_FAILURE;
            }
        }
    
        obj->sensor_name = sensor_list[selectedSensor];
        printf("Sensor selected : %s\n", obj->sensor_name);
    
        obj->table_width = LDC_TABLE_WIDTH;
        obj->table_height = LDC_TABLE_HEIGHT;
        obj->ds_factor = LDC_DS_FACTOR;
    
        /* Display initialization */
        memset(&obj->display_params, 0, sizeof(tivx_display_params_t));
        obj->display_params.opMode = TIVX_KERNEL_DISPLAY_ZERO_BUFFER_COPY_MODE;
        obj->display_params.pipeId = 2;
        obj->display_params.outHeight = 1080;
        obj->display_params.outWidth = 1920;
        obj->display_params.posX = 0;
        obj->display_params.posY = 0;
    
        obj->scaler_enable = vx_false_e;
    
        appPerfPointSetName(&obj->total_perf , "TOTAL");
    
        return status;
    }
    
    vx_status app_deinit(AppObj *obj)
    {
        vx_status status = VX_FAILURE;
        tivxHwaUnLoadKernels(obj->context);
        APP_PRINTF("tivxHwaUnLoadKernels done\n");
    
        tivxImagingUnLoadKernels(obj->context);
        APP_PRINTF("tivxImagingUnLoadKernels done\n");
    
        status = vxReleaseContext(&obj->context);
        if(VX_SUCCESS == status)
        {
            APP_PRINTF("vxReleaseContext done\n");
        }
        else
        {
            printf("Error: vxReleaseContext returned 0x%x \n", status);
        }
        return status;
    }
    
    /*
     * Graph,
     *           viss_config
     *               |
     *               v
     * input_img -> VISS -----> LDC -----> output_img
     *
     */
    
    vx_status app_create_graph(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
        int32_t sensor_init_status = -1;
        obj->configuration = NULL;
        obj->raw = NULL;
        obj->y12 = NULL;
        obj->uv12_c1 = NULL;
        obj->y8_r8_c2 = NULL;
        obj->uv8_g8_c3 = NULL;
        obj->s8_b8_c4 = NULL;
        obj->histogram = NULL;
        obj->h3a_aew_af = NULL;
        unsigned int image_width = obj->width_in;
        unsigned int image_height = obj->height_in;
        uint32_t table_width, table_height;
        vx_imagepatch_addressing_t image_addr;
        vx_rectangle_t rect;
    
        int32_t dcc_buff_size;
    
        const vx_char dcc_2a_user_data_object_name[] = "dcc_2a";
        vx_map_id dcc_2a_buf_map_id;
        uint8_t * dcc_2a_buf;
    
        const vx_char dcc_ldc_user_data_object_name[] = "dcc_ldc";
        vx_map_id dcc_ldc_buf_map_id;
        uint8_t * dcc_ldc_buf;
    
        const vx_char dcc_viss_user_data_object_name[] = "dcc_viss";
        uint8_t * dcc_viss_buf;
        vx_map_id dcc_viss_buf_map_id;
    
        tivx_raw_image raw_image = 0;
        vx_image not_raw_image = 0;
        vx_user_data_object capture_config;
    
        vx_uint8 num_capture_frames = 1;
        tivx_capture_params_t local_capture_config;
        uint32_t buf_id, loopCnt;//, loop_id, num_buf, loopCnt, frameIdx;
        const vx_char capture_user_data_object_name[] = "tivx_capture_params_t";
        uint32_t sensor_features_enabled = 0;
        uint32_t sensor_features_supported = 0;
        uint32_t sensor_dcc_enabled = 0;
        uint32_t sensor_wdr_enabled = 0;
        uint32_t sensor_exp_control_enabled = 0;
        uint32_t sensor_gain_control_enabled = 0;
        vx_image display_image = NULL;
    
        #define Q_DEPTH 1
    
        vx_graph_parameter_queue_params_t graph_parameters_queue_params_list[Q_DEPTH];
    
        printf("Querying %s \n", obj->sensor_name);
        memset(&sensorParams, 0, sizeof(sensorParams));
        status = appQueryImageSensor(obj->sensor_name, &sensorParams);
        if(VX_SUCCESS != status)
        {
            printf("appQueryImageSensor returned %d\n", status);
            return status;
        }
        /*
        Check for supported sensor features.
        It is upto the application to decide which features should be enabled.
        This demo app enables WDR, DCC and 2A if the sensor supports it.
        */
        sensor_features_supported = sensorParams.sensorInfo.features;
    
        if(ISS_SENSOR_FEATURE_COMB_COMP_WDR_MODE == (sensor_features_supported & ISS_SENSOR_FEATURE_COMB_COMP_WDR_MODE))
        {
            APP_PRINTF("WDR mode is supported \n");
            sensor_features_enabled |= ISS_SENSOR_FEATURE_COMB_COMP_WDR_MODE;
            sensor_wdr_enabled = 1;
        }else
        {
            APP_PRINTF("WDR mode is not supported. Defaulting to linear \n");
            sensor_features_enabled |= ISS_SENSOR_FEATURE_LINEAR_MODE;
            sensor_wdr_enabled = 0;
        }
    
        if(ISS_SENSOR_FEATURE_MANUAL_EXPOSURE == (sensor_features_supported & ISS_SENSOR_FEATURE_MANUAL_EXPOSURE))
        {
            APP_PRINTF("Expsoure control is supported \n");
            sensor_features_enabled |= ISS_SENSOR_FEATURE_MANUAL_EXPOSURE;
            sensor_exp_control_enabled = 1;
        }
    
        if(ISS_SENSOR_FEATURE_MANUAL_GAIN == (sensor_features_supported & ISS_SENSOR_FEATURE_MANUAL_GAIN))
        {
            APP_PRINTF("Gain control is supported \n");
            sensor_features_enabled |= ISS_SENSOR_FEATURE_MANUAL_GAIN;
            sensor_gain_control_enabled = 1;
        }
    
        if(ISS_SENSOR_FEATURE_CFG_UC1 == (sensor_features_supported & ISS_SENSOR_FEATURE_CFG_UC1))
        {
            APP_PRINTF("CMS Usecase is supported \n");
            sensor_features_enabled |= ISS_SENSOR_FEATURE_CFG_UC1;
        }
    
        switch(sensorParams.sensorInfo.aewbMode)
        {
            case ALGORITHMS_ISS_AEWB_MODE_NONE:
                obj->aewb_cfg.ae_mode = ALGORITHMS_ISS_AE_DISABLED;
                obj->aewb_cfg.awb_mode = ALGORITHMS_ISS_AWB_MANUAL;
                break;
            case ALGORITHMS_ISS_AEWB_MODE_AWB:
                obj->aewb_cfg.ae_mode = ALGORITHMS_ISS_AE_DISABLED;
                obj->aewb_cfg.awb_mode = ALGORITHMS_ISS_AWB_AUTO;
                break;
            case ALGORITHMS_ISS_AEWB_MODE_AE:
                obj->aewb_cfg.ae_mode = ALGORITHMS_ISS_AE_AUTO;
                obj->aewb_cfg.awb_mode = ALGORITHMS_ISS_AWB_MANUAL;
                break;
            case ALGORITHMS_ISS_AEWB_MODE_AEWB:
                obj->aewb_cfg.ae_mode = ALGORITHMS_ISS_AE_AUTO;
                obj->aewb_cfg.awb_mode = ALGORITHMS_ISS_AWB_AUTO;
                break;
        }
        if(obj->aewb_cfg.ae_mode == ALGORITHMS_ISS_AE_DISABLED)
        {
            if(sensor_exp_control_enabled || sensor_gain_control_enabled )
            {
                obj->aewb_cfg.ae_mode = ALGORITHMS_ISS_AE_MANUAL;
            }
        }
    
        if(ISS_SENSOR_FEATURE_DCC_SUPPORTED == (sensor_features_supported & ISS_SENSOR_FEATURE_DCC_SUPPORTED))
        {
            sensor_features_enabled |= ISS_SENSOR_FEATURE_DCC_SUPPORTED;
            sensor_dcc_enabled = 1;
        }else
        {
            sensor_dcc_enabled = 0;
        }
    
        APP_PRINTF("Sensor width = %d\n", sensorParams.sensorInfo.raw_params.width);
        APP_PRINTF("Sensor height = %d\n", sensorParams.sensorInfo.raw_params.height);
        APP_PRINTF("Sensor DCC ID = %d\n", sensorParams.dccId);
        APP_PRINTF("Sensor Supported Features = 0x%x\n", sensor_features_supported);
        APP_PRINTF("Sensor Enabled Features = 0x%x\n", sensor_features_enabled);
        sensor_init_status = appInitImageSensor(obj->sensor_name, sensor_features_enabled, 0x1);/*Mask = 1 for camera # 0*/
        if(0 != sensor_init_status)
        {
            printf("Error initializing sensor %s \n", obj->sensor_name);
            return VX_FAILURE;
        }
    
        image_width     = sensorParams.sensorInfo.raw_params.width;
        image_height    = sensorParams.sensorInfo.raw_params.height;
        obj->cam_dcc_id = sensorParams.dccId;
    
    /*
    Assuming same dataformat for all exposures.
    This may not be true for staggered HDR. WIll be handled later
        for(count = 0;count<raw_params.num_exposures;count++)
        {
            memcpy(&(raw_params.format[count]), &(sensorProperties.sensorInfo.dataFormat), sizeof(tivx_raw_image_format_t));
        }
    */
    
    /*
    Sensor driver does not support metadata yet.
    */
    
        APP_PRINTF("Creating graph \n");
    
        obj->graph = vxCreateGraph(obj->context);
        APP_ASSERT_VALID_REF(obj->graph);
    
        APP_ASSERT(vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_VPAC_VISS1));
    
        APP_PRINTF("Initializing params for capture node \n");
    
        /* Setting to num buf of capture node */
        APP_PRINTF("Initializing params for capture node \n");
        //raw_image = tivxCreateRawImage(obj->context, &sensorParams.sensorInfo.raw_params);
        not_raw_image = vxCreateImage( obj->context, image_width, image_height, VX_DF_IMAGE_UYVY );
        //not_raw_image = vxCreateImage( obj->context, image_width, image_height, VX_DF_IMAGE_NV12);
        //APP_ASSERT_VALID_REF( not_raw_image );
        obj->num_cap_buf = NUM_BUFS;
    
        /* allocate Input and Output refs, multiple refs created to allow pipelining of graph */
        for(buf_id=0; buf_id<obj->num_cap_buf; buf_id++)
        {
            //obj->cap_frames[buf_id] = vxCreateObjectArray(obj->context, (vx_reference)raw_image, num_capture_frames);
            obj->cap_frames[buf_id] = vxCreateObjectArray(obj->context, (vx_reference)not_raw_image, num_capture_frames);
        }
    
        /* Config initialization */
        tivx_capture_params_init(&local_capture_config);
        local_capture_config.numInst                                    = 1U;
        local_capture_config.numCh                                      = 1U;
        local_capture_config.instId[CAPT_INST_ID]                       = CAPT_INST_ID;
        local_capture_config.instCfg[CAPT_INST_ID].enableCsiv2p0Support = (uint32_t)vx_true_e;
        local_capture_config.instCfg[CAPT_INST_ID].numDataLanes = sensorParams.sensorInfo.numDataLanes;
        APP_PRINTF("local_capture_config.numDataLanes = %d \n", local_capture_config->instCfg.numDataLanes);
    
        for (loopCnt = 0U; loopCnt < local_capture_config.instCfg[CAPT_INST_ID].numDataLanes; loopCnt++)
        {
            local_capture_config.instCfg[CAPT_INST_ID].dataLanesMap[loopCnt] = sensorParams.sensorInfo.dataLanesMap[loopCnt];
            APP_PRINTF("local_capture_config.dataLanesMap[%d] = %d \n", loopCnt, local_capture_config.instCfg[CAPT_INST_ID].dataLanesMap[loopCnt]);
        }
    
        capture_config = vxCreateUserDataObject(obj->context, capture_user_data_object_name, sizeof(tivx_capture_params_t), &local_capture_config);
        APP_PRINTF("capture_config = 0x%p \n", capture_config);
    
        APP_PRINTF("Creating capture node \n");
        obj->capture_node = tivxCaptureNode(obj->graph, capture_config, obj->cap_frames[0]);
        APP_ASSERT_VALID_REF( obj->capture_node );
        APP_PRINTF("obj->capture_node = 0x%p \n", obj->capture_node);
    
        vxReleaseUserDataObject(&capture_config);
    
        vxSetNodeTarget(obj->capture_node, VX_TARGET_STRING, TIVX_TARGET_CAPTURE1);
    
        //obj->raw = (tivx_raw_image)vxGetObjectArrayItem(obj->cap_frames[0], 0);
        obj->not_raw = (vx_image)vxGetObjectArrayItem(obj->cap_frames[0], 0);
        
        //tivxReleaseRawImage(&raw_image);
        vxReleaseImage( &not_raw_image );
    
        if ( sensor_dcc_enabled )
        {
            printf( " sensor dcc enabled \n" );
        }
    
        if ( sensor_wdr_enabled )
        {
            printf( " sensor wdr enabled \n" );
        }
    
        
    
    //display_image = obj->not_raw;
    //display_image = (vx_image)obj->raw;
    #if 0
        if(NULL == display_image)
        {
            printf("Error : Display input is uninitialized \n");
            return VX_FAILURE;
        }
        else
        {
            obj->display_params.posX = (1920U - obj->display_params.outWidth)/2;
            obj->display_params.posY = (1080U - obj->display_params.outHeight)/2;
            obj->display_param_obj = vxCreateUserDataObject(obj->context, "tivx_display_params_t", sizeof(tivx_display_params_t), &obj->display_params);
            obj->displayNode = tivxDisplayNode(obj->graph, obj->display_param_obj, display_image);
        }
    
        vxSetNodeTarget(obj->displayNode, VX_TARGET_STRING, TIVX_TARGET_DISPLAY1);
        APP_PRINTF("Display Set Target done\n");
    #endif
        int graph_parameter_num = 0;
    
        /* input @ node index 1, becomes graph parameter 0 */
        add_graph_parameter_by_node_index(obj->graph, obj->capture_node, 1);
    
        /* set graph schedule config such that graph parameter @ index 0 is enqueuable */
        graph_parameters_queue_params_list[graph_parameter_num].graph_parameter_index = 0;
        graph_parameters_queue_params_list[graph_parameter_num].refs_list_size = obj->num_cap_buf;
        graph_parameters_queue_params_list[graph_parameter_num].refs_list = (vx_reference*)&(obj->cap_frames[0]);
        graph_parameter_num++;
    
        tivxSetGraphPipelineDepth(obj->graph, obj->num_cap_buf);
    
    
        /* Schedule mode auto is used, here we dont need to call vxScheduleGraph
         * Graph gets scheduled automatically as refs are enqueued to it
         */
        vxSetGraphScheduleConfig(obj->graph,
                VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO,
                Q_DEPTH,
                graph_parameters_queue_params_list
        );
        APP_PRINTF("vxSetGraphScheduleConfig done\n");
    
        status = vxVerifyGraph(obj->graph);
        APP_ASSERT(status==VX_SUCCESS);
    
    
        tivxExportGraphToDot(obj->graph, ".", "single_cam_graph");
    
        APP_PRINTF("app_create_graph exiting\n");
        return status;
    }
    
    vx_status app_delete_graph(AppObj *obj)
    {
        uint32_t buf_id;
        vx_status status = VX_SUCCESS;
    
        if(NULL != obj->capture_node)
        {
            APP_PRINTF("releasing capture node\n");
            status |= vxReleaseNode(&obj->capture_node);
        }
    
        if(NULL != obj->node_viss)
        {
            APP_PRINTF("releasing node_viss\n");
            status |= vxReleaseNode(&obj->node_viss);
        }
    
        if(NULL != obj->node_aewb)
        {
            APP_PRINTF("releasing node_aewb\n");
            status |= vxReleaseNode(&obj->node_aewb);
        }
    
        if(NULL != obj->displayNode)
        {
            APP_PRINTF("releasing displayNode\n");
            status |= vxReleaseNode(&obj->displayNode);
        }
    
        status |= tivxReleaseRawImage(&obj->raw);
        APP_PRINTF("releasing raw image done\n");
    
       for(buf_id=0; buf_id<obj->num_cap_buf; buf_id++)
        {
           if(NULL != obj->cap_frames[buf_id])
           {
            APP_PRINTF("releasing cap_frame # %d\n", buf_id);
            status |= vxReleaseObjectArray(&(obj->cap_frames[buf_id]));
        }
       }
    
        for(buf_id=0; buf_id<obj->num_viss_out_buf; buf_id++)
        {
          if(NULL != obj->viss_out_luma[buf_id])
          {
            APP_PRINTF("releasing y8 buffer # %d\n", buf_id);
            status |= vxReleaseImage(&(obj->viss_out_luma[buf_id]));
        }
       }
    
        if(NULL != obj->y12)
        {
            APP_PRINTF("releasing y12\n");
            status |= vxReleaseImage(&obj->y12);
        }
    
        if(NULL != obj->uv12_c1)
        {
            APP_PRINTF("releasing uv12_c1\n");
            status |= vxReleaseImage(&obj->uv12_c1);
        }
    
        if(NULL != obj->s8_b8_c4)
        {
            APP_PRINTF("releasing s8_b8_c4\n");
            status |= vxReleaseImage(&obj->s8_b8_c4);
        }
    
        if(NULL != obj->y8_r8_c2)
        {
            APP_PRINTF("releasing y8_r8_c2\n");
            status |= vxReleaseImage(&obj->y8_r8_c2);
        }
    
        if(NULL != obj->uv8_g8_c3)
        {
            APP_PRINTF("releasing uv8_g8_c3\n");
            status |= vxReleaseImage(&obj->uv8_g8_c3);
        }
    
        if(NULL != obj->histogram)
        {
            APP_PRINTF("releasing histogram\n");
            status |= vxReleaseDistribution(&obj->histogram);
        }
    
        if(NULL != obj->configuration)
        {
            APP_PRINTF("releasing configuration\n");
            status |= vxReleaseUserDataObject(&obj->configuration);
    
        }
    
        if (NULL != obj->ae_awb_result)
        {
            status |= vxReleaseUserDataObject(&obj->ae_awb_result);
            APP_PRINTF("releasing ae_awb_result done\n");
        }
    
        if(NULL != obj->h3a_aew_af)
        {
            APP_PRINTF("releasing h3a_aew_af\n");
            status |= vxReleaseUserDataObject(&obj->h3a_aew_af);
        }
    
        if(NULL != obj->aewb_config)
        {
            APP_PRINTF("releasing aewb_config\n");
            status |= vxReleaseUserDataObject(&obj->aewb_config);
        }
    
        if(NULL != obj->dcc_param_viss)
        {
            APP_PRINTF("releasing VISS DCC Data Object\n");
            status |= vxReleaseUserDataObject(&obj->dcc_param_viss);
        }
    
        if(NULL != obj->display_param_obj)
        {
            APP_PRINTF("releasing Display Param Data Object\n");
            status |= vxReleaseUserDataObject(&obj->display_param_obj);
        }
    /*
        if(NULL != obj->dcc_param_2a)
        {
            APP_PRINTF("releasing 2A DCC Data Object\n");
            status |= vxReleaseUserDataObject(&obj->dcc_param_2a);
        }*/
    
        if(NULL != obj->dcc_param_ldc)
        {
            APP_PRINTF("releasing LDC DCC Data Object\n");
            status |= vxReleaseUserDataObject(&obj->dcc_param_ldc);
        }
    
        if (obj->ldc_enable)
        {
            if (NULL != obj->mesh_img)
            {
                APP_PRINTF("releasing LDC Mesh Image \n");
                status |= vxReleaseImage(&obj->mesh_img);
            }
    
            if (NULL != obj->ldc_out)
            {
                APP_PRINTF("releasing LDC Output Image \n");
                status |= vxReleaseImage(&obj->ldc_out);
            }
    
            if (NULL != obj->mesh_params_obj)
            {
                APP_PRINTF("releasing LDC Mesh Parameters Object\n");
                status |= vxReleaseUserDataObject(&obj->mesh_params_obj);
            }
    
            if (NULL != obj->ldc_param_obj)
            {
                APP_PRINTF("releasing LDC Parameters Object\n");
                status |= vxReleaseUserDataObject(&obj->ldc_param_obj);
            }
    
            if (NULL != obj->region_params_obj)
            {
                APP_PRINTF("releasing LDC Region Parameters Object\n");
                status |= vxReleaseUserDataObject(&obj->region_params_obj);
            }
    
            if(NULL != obj->node_ldc)
            {
                APP_PRINTF("releasing LDC Node \n");
                status |= vxReleaseNode(&obj->node_ldc);
            }
        }
        if(vx_true_e == obj->scaler_enable)
        {
            if (NULL != obj->scaler_out_img)
            {
                APP_PRINTF("releasing Scaler Output Image \n");
                status |= vxReleaseImage(&obj->scaler_out_img);
            }
    
            if(NULL != obj->scalerNode)
            {
                APP_PRINTF("releasing Scaler Node \n");
                status |= vxReleaseNode(&obj->scalerNode);
            }
    
            if (NULL != obj->sc_coeff_obj)
            {
                APP_PRINTF("release Scalar coefficient data object \n");
                status |= vxReleaseUserDataObject(&obj->sc_coeff_obj);
            }
        }
    
        APP_PRINTF("releasing graph\n");
        status |= vxReleaseGraph(&obj->graph);
        APP_PRINTF("releasing graph done\n");
        return status;
    }
    
    vx_status app_run_graph(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
        vx_uint32 i;
        vx_uint32 frm_loop_cnt;
    
        uint32_t buf_id;
        uint32_t num_refs_capture;
        vx_object_array out_capture_frames;
        int graph_parameter_num = 0;
    
        if(NULL == obj->sensor_name)
        {
            printf("sensor name is NULL \n");
            return VX_FAILURE;
        }
        status = appStartImageSensor(obj->sensor_name, 0x1);
    
        /* Enqueue buf for pipe up but don't trigger graph execution */
        for(buf_id=0; buf_id<obj->num_cap_buf-1; buf_id++)
        {
            graph_parameter_num = 0;
            tivxGraphParameterEnqueueReadyRef(obj->graph, graph_parameter_num, (vx_reference*)&(obj->cap_frames[buf_id]), 1, TIVX_GRAPH_PARAMETER_ENQUEUE_FLAG_PIPEUP);
            graph_parameter_num++;
        }
    
        graph_parameter_num = 0;
        /* Need to trigger again since display holds on to a buffer */
        vxGraphParameterEnqueueReadyRef(obj->graph, graph_parameter_num, (vx_reference*)&obj->cap_frames[obj->num_cap_buf-1], 1);
        graph_parameter_num++;
    
        /*
            The application reads and  processes the same image "frm_loop_cnt" times
            The output may change because on VISS, parameters are updated every frame based on AEWB results
            AEWB result is avaialble after 1 frame and is applied after 2 frames
            Therefore, first 2 output images will have wrong colors
        */
        frm_loop_cnt = obj->num_frames_to_run;
        frm_loop_cnt += obj->num_cap_buf;
    
        if(obj->is_interactive)
        {
            /* in interactive mode loop for ever */
            frm_loop_cnt  = 0xFFFFFFFF;
        }
    
        for(i=0; i<frm_loop_cnt; i++)
        {
            printf("enque deque \n");
            appPerfPointBegin(&obj->total_perf);
            printf("appPerfPointBegin \n");
            graph_parameter_num = 0;
            vxGraphParameterDequeueDoneRef(obj->graph, graph_parameter_num, (vx_reference*)&out_capture_frames, 1, &num_refs_capture);
            graph_parameter_num++;
            printf("deque done \n");
    
            APP_PRINTF(" frm_loop_cnt %d...\n", i);
            graph_parameter_num = 0;
            vxGraphParameterEnqueueReadyRef(obj->graph, graph_parameter_num, (vx_reference*)&out_capture_frames, 1);
            printf("enque done \n");
            graph_parameter_num++;
    
            appPerfPointEnd(&obj->total_perf);
    
            if(obj->stop_task)
            {
                break;
            }
        }
    
        vxWaitGraph(obj->graph);
    
    /* Dequeue buf for pipe down */
    
        for(buf_id=0; buf_id<obj->num_cap_buf-2; buf_id++)
        {
            APP_PRINTF(" Dequeuing capture # %d...\n", buf_id);
            graph_parameter_num = 0;
            vxGraphParameterDequeueDoneRef(obj->graph, graph_parameter_num, (vx_reference*)&out_capture_frames, 1, &num_refs_capture);
            graph_parameter_num++;
        }
    
        status = appStopImageSensor(obj->sensor_name, 0x1);
        return status;
    }
    
    static void app_run_task(void *app_var)
    {
        AppObj *obj = (AppObj *)app_var;
    
        appPerfStatsCpuLoadResetAll();
    
        app_run_graph(obj);
    
        obj->stop_task_done = 1;
    }
    
    static int32_t app_run_task_create(AppObj *obj)
    {
        tivx_task_create_params_t params;
        int32_t status;
    
        tivxTaskSetDefaultCreateParams(&params);
        params.task_main = app_run_task;
        params.app_var = obj;
    
        obj->stop_task_done = 0;
        obj->stop_task = 0;
    
        status = tivxTaskCreate(&obj->task, &params);
    
        return status;
    }
    
    static void app_run_task_delete(AppObj *obj)
    {
        while(obj->stop_task_done==0)
        {
             tivxTaskWaitMsecs(100);
        }
    
        tivxTaskDelete(&obj->task);
    }
    
    static char menu[] = {
        "\n"
        "\n =========================="
        "\n Demo : Single Camera w/ 2A"
        "\n =========================="
        "\n"
        "\n p: Print performance statistics"
        "\n"
    #ifdef _APP_DEBUG_
        "\n s: Save Sensor RAW, VISS Output and H3A output images to File System"
        "\n"
    #endif
        "\n e: Export performance statistics"
        "\n"
        "\n x: Exit"
        "\n"
        "\n Enter Choice: "
    };
    
    static vx_status app_run_graph_interactive(AppObj *obj)
    {
        vx_status status;
        uint32_t done = 0;
        char ch;
        FILE *fp;
        app_perf_point_t *perf_arr[1];
    
        status = app_run_task_create(obj);
        if(status!=0)
        {
            printf("ERROR: Unable to create task\n");
        }
        else
        {
            while(!done)
            {
                printf(menu);
                ch = getchar();
                printf("\n");
    
                switch(ch)
                {
                    case 'p':
                        appPerfStatsPrintAll();
                        tivx_utils_graph_perf_print(obj->graph);
                        appPerfPointPrint(&obj->total_perf);
                        printf("\n");
                        appPerfPointPrintFPS(&obj->total_perf);
                        printf("\n");
                        break;
    #ifdef _APP_DEBUG_
                    case 's':
                        save_debug_images(obj);
                        break;
    #endif
                    case 'e':
                        perf_arr[0] = &obj->total_perf;
                        fp = appPerfStatsExportOpenFile(".", "apps_basic_demos_single_camera");
                        if (NULL != fp)
                        {
                            appPerfStatsExportAll(fp, perf_arr, 1);
                            tivx_utils_graph_perf_export(fp, obj->graph);
                            appPerfStatsExportCloseFile(fp);
                            appPerfStatsResetAll();
                        }
                        else
                        {
                            printf("fp is null\n");
                        }
                        break;
                    case 'x':
                        obj->stop_task = 1;
                        done = 1;
                        break;
                }
            }
            app_run_task_delete(obj);
        }
        status = appStopImageSensor(obj->sensor_name, 0x1);
        return status;
    }
    
    static void app_show_usage(int argc, char* argv[])
    {
        printf("\n");
        printf(" Single Camera Demo - (c) Texas Instruments 2019\n");
        printf(" ========================================================\n");
        printf("\n");
        printf(" Usage,\n");
        printf("  %s --cfg <config file>\n", argv[0]);
        printf("\n");
    }
    
    #ifdef _APP_DEBUG_
    #define MAX_FNAME 128
    int save_debug_images(AppObj *obj)
    {
        int num_bytes_io = 0;
        static int file_index = 0;
        char raw_image_fname[MAX_FNAME];
        char yuv_image_fname[MAX_FNAME];
        char h3a_image_fname[MAX_FNAME];
        char failsafe_test_data_path[3] = "./";
        char * test_data_path = app_get_test_file_path();
        if(NULL == test_data_path)
        {
            printf("Test data path is NULL. Defaulting to current folder \n");
            test_data_path = failsafe_test_data_path;
        }
    
        snprintf(raw_image_fname, MAX_FNAME, "%s/%s_%04d.raw", test_data_path, "img", file_index);
        printf("RAW file name %s \n", raw_image_fname);
        num_bytes_io = write_output_image_raw(raw_image_fname, (tivx_raw_image)obj->not_raw);
        //num_bytes_io = write_output_image_raw(raw_image_fname, obj->raw);
        if(num_bytes_io < 0)
        {
            printf("Error writing to RAW file \n");
            return VX_FAILURE;
        }
    
        snprintf(yuv_image_fname, MAX_FNAME, "%s/%s_%04d.yuv", test_data_path, "img_viss", file_index);
        printf("YUV file name %s \n", yuv_image_fname);
        num_bytes_io = write_output_image_nv12_8bit(yuv_image_fname, obj->not_raw);
        //num_bytes_io = write_output_image_nv12_8bit(yuv_image_fname, (tivx_raw_image)obj->raw);
        if(num_bytes_io < 0)
        {
            printf("Error writing to VISS NV12 file \n");
            return VX_FAILURE;
        }
    /*
        if(obj->scaler_enable)
        {
            snprintf(yuv_image_fname, MAX_FNAME, "%s/%s_%04d.yuv", test_data_path, "img_msc", file_index);
            printf("YUV file name %s \n", yuv_image_fname);
            num_bytes_io = write_output_image_nv12_8bit(yuv_image_fname, obj->scaler_out_img);
            if(num_bytes_io < 0)
            {
                printf("Error writing to MSC NV12 file \n");
                return VX_FAILURE;
            }
        }
    
        if(obj->ldc_enable)
        {
            snprintf(yuv_image_fname, MAX_FNAME, "%s/%s_%04d.yuv", test_data_path, "img_ldc", file_index);
            printf("YUV file name %s \n", yuv_image_fname);
            num_bytes_io = write_output_image_nv12_8bit(yuv_image_fname, obj->ldc_out);
            if(num_bytes_io < 0)
            {
                printf("Error writing to LDC NV12 file \n");
                return VX_FAILURE;
            }
        }
    
        snprintf(h3a_image_fname, MAX_FNAME, "%s/%s_%04d.bin", test_data_path, "h3a", file_index);
        printf("H3A file name %s \n", h3a_image_fname);
        num_bytes_io = write_h3a_image(h3a_image_fname, obj->h3a_aew_af);
        if(num_bytes_io < 0)
        {
            printf("Error writing to H3A file \n");
            return VX_FAILURE;
        }*/
    
        file_index++;
        return (file_index-1);
    }
    
    vx_int32 write_output_image_fp(FILE * fp, vx_image out_image)
    {
        vx_uint32 width, height;
        vx_df_image df;
        vx_imagepatch_addressing_t image_addr;
        vx_rectangle_t rect;
        vx_map_id map_id1, map_id2;
        void *data_ptr1, *data_ptr2;
        vx_uint32 num_bytes_per_pixel = 1;
        vx_uint32 num_luma_bytes_written_to_file=0;
    	vx_uint32 num_chroma_bytes_written_to_file=0;
    	vx_uint32 num_bytes_written_to_file=0;
        vx_uint32 imgaddr_width, imgaddr_height, imgaddr_stride;
    	int i;
    
        vxQueryImage(out_image, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
        vxQueryImage(out_image, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
        vxQueryImage(out_image, VX_IMAGE_FORMAT, &df, sizeof(vx_df_image));
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = width;
        rect.end_y = height;
    
        printf("out width =  %d\n", width);
        printf("out height =  %d\n", height);
        printf("out format =  %d\n", df);
    
        vxMapImagePatch(out_image,
            &rect,
            0,
            &map_id1,
            &image_addr,
            &data_ptr1,
            VX_WRITE_ONLY,
            VX_MEMORY_TYPE_HOST,
            VX_NOGAP_X
            );
    
    
        if(!data_ptr1)
        {
            printf("data_ptr1 is NULL \n");
            return -1;
        }
    
        imgaddr_width  = image_addr.dim_x;
        imgaddr_height = image_addr.dim_y;
        imgaddr_stride = image_addr.stride_y;
    
        num_luma_bytes_written_to_file = 0;
    
     /*   for(i=0;i<imgaddr_height;i++)
        {
            num_luma_bytes_written_to_file  += fwrite(data_ptr1, 1, imgaddr_width*num_bytes_per_pixel, fp);
            data_ptr1 += imgaddr_stride;
       }*/
        fwrite(data_ptr1, 1, width*height*2, fp);
    
        vxUnmapImagePatch(out_image, map_id1);
    
        fflush(fp);
    
    	vxMapImagePatch(out_image,
            &rect,
            1,
            &map_id2,
            &image_addr,
            &data_ptr2,
            VX_WRITE_ONLY,
            VX_MEMORY_TYPE_HOST,
            VX_NOGAP_X
            );
    
        if(!data_ptr2)
        {
            printf("data_ptr2 is NULL \n");
            return -1;
        }
    
        imgaddr_width  = image_addr.dim_x;
        imgaddr_height = image_addr.dim_y;
        imgaddr_stride = image_addr.stride_y;
    
        num_chroma_bytes_written_to_file = 0;
        
        /*for(i=0;i<imgaddr_height/2;i++)
        {
            num_chroma_bytes_written_to_file  += fwrite(data_ptr2, 1, imgaddr_width*num_bytes_per_pixel, fp);
            data_ptr2 += imgaddr_stride;
        }*/
    
        fflush(fp);
    
        vxUnmapImagePatch(out_image, map_id2);
    
        num_bytes_written_to_file = num_luma_bytes_written_to_file + num_chroma_bytes_written_to_file;
    	printf("Written %d bytes \n", num_bytes_written_to_file);
    
        return num_bytes_written_to_file;
    }
    
    vx_int32 write_output_image_nv12_8bit(char * file_name, vx_image out_nv12)
    {
        FILE * fp = fopen(file_name, "wb");
        if(!fp)
        {
            APP_PRINTF("Unable to open file %s\n", file_name);
            return -1;
        }
        vx_uint32 len1 = write_output_image_fp(fp, out_nv12);
        fclose(fp);
        APP_PRINTF("%d bytes written to %s\n", len1, file_name);
        return len1;
    }
    
    vx_int32 write_output_image_raw(char * file_name, tivx_raw_image raw_image)
    {
        FILE * fp = fopen(file_name, "wb");
        vx_uint32 width, height, i;
        vx_imagepatch_addressing_t image_addr;
        vx_rectangle_t rect;
        vx_map_id map_id;
        void *data_ptr;
        vx_uint32 num_bytes_per_pixel = 2; /*Mayank : Hardcoded to 12b Unpacked format*/
        vx_uint32 num_bytes_written_to_file;
        tivx_raw_image_format_t format;
        vx_uint32 imgaddr_width, imgaddr_height, imgaddr_stride;
    
        if(!fp)
        {
            APP_PRINTF("Unable to open file %s\n", file_name);
            return -1;
        }
    
        tivxQueryRawImage(raw_image, TIVX_RAW_IMAGE_WIDTH, &width, sizeof(vx_uint32));
        tivxQueryRawImage(raw_image, TIVX_RAW_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
        tivxQueryRawImage(raw_image, TIVX_RAW_IMAGE_FORMAT, &format, sizeof(format));
    
        APP_PRINTF("in width =  %d\n", width);
        APP_PRINTF("in height =  %d\n", height);
        APP_PRINTF("in format =  %d\n", format.pixel_container);
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = width;
        rect.end_y = height;
    
        tivxMapRawImagePatch(raw_image,
            &rect,
            0,
            &map_id,
            &image_addr,
            &data_ptr,
            VX_READ_ONLY,
            VX_MEMORY_TYPE_HOST,
            TIVX_RAW_IMAGE_PIXEL_BUFFER
            );
    
        if(!data_ptr)
        {
            APP_PRINTF("data_ptr is NULL \n");
            fclose(fp);
            return -1;
        }
        num_bytes_written_to_file = 0;
    
        imgaddr_width  = image_addr.dim_x;
        imgaddr_height = image_addr.dim_y;
        imgaddr_stride = image_addr.stride_y;
    
        for(i=0;i<imgaddr_height;i++)
        {
            num_bytes_written_to_file += fwrite(data_ptr, 1, imgaddr_width*num_bytes_per_pixel, fp);
            data_ptr += imgaddr_stride;
        }
    
        tivxUnmapRawImagePatch(raw_image, map_id);
    
        fflush(fp);
        fclose(fp);
        APP_PRINTF("%d bytes written to %s\n", num_bytes_written_to_file, file_name);
        return num_bytes_written_to_file;
    }
    
    vx_int32 write_h3a_image(char * file_name, vx_user_data_object out_h3a)
    {
        FILE * fp = fopen(file_name, "wb");
        tivx_h3a_data_t *h3a_data = NULL;
        vx_map_id h3a_buf_map_id;
        vx_uint8 *h3a_payload = NULL;
        vx_uint32 h3a_size = 0;
        if(!fp)
        {
            APP_PRINTF("Unable to open file %s\n", file_name);
            return -1;
        }
    
        vxMapUserDataObject(
                out_h3a,
                0,
                sizeof(tivx_h3a_data_t),
                &h3a_buf_map_id,
                (void **)&h3a_data,
                VX_READ_ONLY,
                VX_MEMORY_TYPE_HOST,
                0
            );
    
        h3a_payload = h3a_data->data;// + 12; /*C model 12-byte header*/
        h3a_size = fwrite(h3a_payload, 1, TIVX_VPAC_VISS_MAX_H3A_STAT_NUMBYTES, fp);
        APP_PRINTF("%d bytes saved from H3A output buffer \n", h3a_size);
        fflush(fp);
        fclose(fp);
        vxUnmapUserDataObject(out_h3a, h3a_buf_map_id);
    
        return h3a_size;
    }
    #endif //_APP_DEBUG_
    
    vx_char default_sensor_name[ISS_SENSORS_MAX_NAME] = SENSOR_SONY_IMX390_UB953_D3;
    void app_set_cfg_default(AppObj *obj)
    {
        obj->width_in = 1920;
        obj->height_in = 1080;
        obj->width_out = 1920;
        obj->height_out = 1080;
        obj->is_interactive = 1;
        obj->ldc_enable = 0;
        obj->sensor_name = default_sensor_name;
    }
    
    static void app_parse_cfg_file(AppObj *obj, char *cfg_file_name)
    {
        FILE *fp = fopen(cfg_file_name, "r");
        char line_str[1024];
        char *token;
    
        if(fp==NULL)
        {
            printf("# ERROR: Unable to open config file [%s]. Switching to interactive mode\n", cfg_file_name);
            obj->is_interactive = 1;
        }
    
        while(fgets(line_str, sizeof(line_str), fp)!=NULL)
        {
            char s[]=" \t";
    
            if (strchr(line_str, '#'))
            {
                continue;
            }
    
            /* get the first token */
            token = strtok(line_str, s);
            if(strcmp(token, "sensor_index")==0)
            {
                token = strtok(NULL, s);
                obj->sensor_sel = atoi(token);
                printf("sensor_selection = [%d]\n", obj->sensor_sel);
            }
            else
            if(strcmp(token, "ldc_enable")==0)
            {
                token = strtok(NULL, s);
                obj->ldc_enable = atoi(token);
                printf("ldc_enable = [%d]\n", obj->ldc_enable);
            }
            else
            if(strcmp(token, "num_frames_to_run")==0)
            {
                token = strtok(NULL, s);
                obj->num_frames_to_run = atoi(token);
                printf("num_frames_to_run = [%d]\n", obj->num_frames_to_run);
            }
            else
            if(strcmp(token, "is_interactive")==0)
            {
                token = strtok(NULL, s);
                obj->is_interactive = atoi(token);
                printf("is_interactive = [%d]\n", obj->is_interactive);
            }
            else
            {
                APP_PRINTF("Invalid token [%s]\n", token);
            }
        }
    
        fclose(fp);
    
        if(obj->width_in<128)
            obj->width_in = 128;
        if(obj->height_in<128)
            obj->height_in = 128;
        if(obj->width_out<128)
            obj->width_out = 128;
        if(obj->height_out<128)
            obj->height_out = 128;
    
    }
    
    vx_status app_parse_cmd_line_args(AppObj *obj, int argc, char *argv[])
    {
        app_set_cfg_default(obj);
    
        int i;
        if(argc==1)
        {
            app_show_usage(argc, argv);
            printf("Defaulting to interactive mode \n");
            obj->is_interactive = 1;
            return VX_SUCCESS;
        }
    
        for(i=0; i<argc; i++)
        {
            if(strcmp(argv[i], "--cfg")==0)
            {
                i++;
                if(i>=argc)
                {
                    app_show_usage(argc, argv);
                }
                app_parse_cfg_file(obj, argv[i]);
                break;
            }
            else
            if(strcmp(argv[i], "--help")==0)
            {
                app_show_usage(argc, argv);
                return VX_FAILURE;
            }
        }
        return VX_SUCCESS;
    }
    
    
    
    #ifdef _APP_DEBUG_
    vx_int32 write_output_image_nv12(char * file_name, vx_image out_nv12)
    {
        FILE * fp = fopen(file_name, "wb");
        if(!fp)
        {
            APP_PRINTF("Unable to open file %s\n", file_name);
            return -1;
        }
        vx_uint32 len1 = write_output_image_fp(fp, out_nv12);
        fclose(fp);
        APP_PRINTF("%d bytes written to %s\n", len1, file_name);
        return len1;
    }
    #endif
    
    
    AppObj gAppObj;
    
    int app_single_cam_main(int argc, char* argv[])
    {
        AppObj *obj = &gAppObj;
        vx_status status = VX_FAILURE;
        status = app_parse_cmd_line_args(obj, argc, argv);
        if(VX_SUCCESS == status)
        {
            status = app_init(obj);
            if(VX_SUCCESS == status)
            {
                APP_PRINTF("app_init done\n");
                status = app_create_graph(obj);
                if(VX_SUCCESS == status)
                {
                    APP_PRINTF("app_create_graph done\n");
                    if(obj->is_interactive)
                    {
                        status = app_run_graph_interactive(obj);
                    }
                    else
                    {
                        status = app_run_graph(obj);
                    }
                    if(VX_SUCCESS == status)
                    {
                        APP_PRINTF("app_run_graph done\n");
                        status = app_delete_graph(obj);
                        if(VX_SUCCESS == status)
                        {
                            APP_PRINTF("app_delete_graph done\n");
                        }
                        else
                        {
                            printf("Error : app_delete_graph returned 0x%x \n", status);
                        }
                    }
                    else
                    {
                        printf("Error : app_run_graph_xx returned 0x%x \n", status);
                    }
                }
                else
                {
                    printf("Error : app_create_graph returned 0x%x is_interactive =%d  \n", status, obj->is_interactive);
                }
            }
            else
            {
                printf("Error : app_init returned 0x%x \n", status);
            }
            status = app_deinit(obj);
            if(VX_SUCCESS == status)
            {
                APP_PRINTF("app_deinit done\n");
            }
            else
            {
                printf("Error : app_deinit returned 0x%x \n", status);
            }
            appDeInitImageSensor(obj->sensor_name);
        }
        else
        {
            printf("Error: app_parse_cmd_line_args returned 0x%x \n", status);
        }
    
        return 0;
    }
    

    3162.isx016_serdes_config.h

    Regards,

    Kim

  • Hi Kim,

    Are you using Fusion platform? Then yes, there is no issue between UB960 and TDA4x. This has been validated for multiple sensors..

    What is the output format from your sensor? Is your sensor and SERDES configured correctly?

    Did you see lock status bit set in UB960? Can you also check line status register in UB960 to confirm it is receiving valid data?

    Rgds,

    Brijesh

  • Hello Brijesh,

    I use Fusion Application board rev.C.

    My sensor Output is YUV422. (UYVY)

    I think, It seems that the sensor settings are correct.

    My sensor spec,

    Image Sensor : ISX016

    Serializer : UB913

    Deserializer : UB960

    My Serdes config is

    Serializer

        {0x01, 0x30, 0x80},
        {0x03, 0xC5, 0x10},
        {0x0D, 0x55, 0x10},
        {0x05, 0x15, 0x10},
        {0x11, SERDES_I2C_SCL_HOLD_TIME, 0x10},
        {0x12, SERDES_I2C_SCL_HOLD_TIME, 0x10},
        {0xFFFF, 0x00, 0x0} //End of script

    Deserializer

        {0x4C, 0x01,0x10},
        {0x58, 0x58,0x10},
        {0xD5, 0xF0,0x10},
        {0x6D, 0x6F,0x10},
        {0x70, 0x1F,0x10},

        //{0x5B, (BSPUTILS_SER_ID_ADDR << 1U), 0x10}, 
        {0x5C, (SER_0_I2C_ALIAS << 1U), 0x10},   //E8(8bit)      => 74 (7bit)
        {0x5D, ISX016_I2C_ADDR<<1U, 0x10},       //34(8bit)     => 1A (7bit)
        {0x65, (SENSOR_0_I2C_ALIAS << 1U), 0x10},//80(8bit)     => 40 (7bit)
        {0x32, 0x01,0x0},
        {0x20, 0x00, 0x10},

        {0x21, 0x03, 0x0},
        {0xFFFF, 0x00, 0x0} //End of script

    And,

    I also said in the previous answer, LOCK_STS is set. (value is 1).

    I think, UB960 receiving valid data is 0x91(CSI0_FRAME_COUNT_LO)

    It was fixed at 0x01.

    Maybe it is fixed to 1 because it cannot deque?

    Thanks your answer, and any Advise.

    Regards,

    Kim

  • Hi Kim,

    FRAME_COUNT should keep incrementing. There is also LINE_SIZE register in UB960, can you check if LINE_SIZE is correct from UB960?

    Rgds,

    Brijesh

  • Hi Brijesh,

    I had some Deserializer changes.

    This is Deserializer value.


    0x91 (CSI0_FRAME_COUNT_LO) had a change. (01 -> 28)


    I think, the LINE_SIZE is 0x94 ( CSI0_LINE_COUNT_HI ) , 0x95 ( CSI0_LINE_COUNT_LO ).


    As you can see in the picture attached, Its value is 0.


    Is there any reason to be expected?

    Regards,

    Kim

  • Hi Kim,

    This means UB960 is not receiving data.. Could you please check your Ub960 configuration? Is the channel correct? and each channel correctly configured?

    Rgds,

    Brijesh

  • Hello Brijesh, 

    -----------------------------------------------------------------------------------------------------------------------------

        {0x4C, 0x01,0x10}, // # port 0 camera
        {0x58, 0x58,0x10},  // BC_FREQ_SELECT // Channel Frequency 2.5Mbps (UB913A)
        {0x6D, 0x6F,0x10},  // FPD3_MODE  // RAW10 Mode 
        {0x70, 0x1F,0x10},  // FAW10_VC & RAW10_DT // 

        //{0x5B, (BSPUTILS_SER_ID_ADDR << 1U), 0x10}, 
        {0x5C, (SER_0_I2C_ALIAS << 1U), 0x10},   //Serializer Alias Address
        {0x5D, ISX016_I2C_ADDR<<1U, 0x10},       //Image sensor Address
        {0x65, (SENSOR_0_I2C_ALIAS << 1U), 0x10},//Image sensor Alias Address
        {0x32, 0x01,0x0},       // TX_WRITE_PORT_0 // write enable
        {0x20, 0x00, 0x10},    // 

        {0x21, 0x03, 0x0},
        {0xFFFF, 0x00, 0x0} //End of script
    -----------------------------------------------------------------------------------------------------------------------------
    This is my deserializer main setup.
     
    I refer to the datasheet and questionnaire posted on forum.
     
    Perhaps, I think that the device driver creation code is wrong.
    I referenced and modified the existing imx390 code. ( from imaging / sensor_drv / imx390 )
     
     
    If I modify it wrong in this code, could it cause the my problem?
     
     
    Regards,
    Kim
     
     
  • Hi Kim,

    I think there is a UB960 start streaming register (register 0x33), That needs to be enabled only after CSI driver is created. This is taken care in the IMX390 SERDES configuration. Could you please check if this is taken care in your register settings?

    Regards,

    Brijesh 

  • Hello Brijesh,


    As in the previous reply, 0x33 is set to 0x03 when streaming start.


    but, it is enabled as 0x01 before streaming starts.

    I know that the value should not be set before streaming starts.


    Is it correct that the value is 0x01 before streaming start?

    Regards,

    Kim

  • Hi Kim

    Yes, the bit0 in the register 0x33 starts the CSI output.

    Just after setting value in register 0x1f, set the bit0 to 0 in 0x33 register and then just before starting fvid2 driver, set the value 0x3 to 0x33 register.

    Rgds,

    Brijesh

  • Hello Brijesh


    Does the 0x1f you mean the 0x1f value of the 0x70 (RAW10_ID Register) register?

    Or does it mean the 0x1f (CSI_PLL_CTL Register) register?

     

    Regards,

    Kim

  • Hi Kim,

    I meant CSI_PLL_CTL register.

    Just after setting CSI output frequency, please disable the output and then do all the settings..

    Rgds,

    Brijesh

  • Hello, Brijesh


    I disabled the output after frequency setting and I do all the settings after.

    As a result, The values of register was changed.
    0x91( CSI0_FRAME_COUNT_LO),
    0x93( CSI0_FRAME_ERR_COUNT_LO),
    0x94( CSI0_LINE_COUNT_HI ),
    0x95( CSI0_LINE_COUNT_LO ).

    [  regAddr = 90 | 07 7e 07 9a ff ff ff ff 00 00 00 00 00 00 00 00  ]

    Previously, these registers didn't have any values.
    But now they had some values.

    But I still can't get any image data.


    Is it correct that the register value comes out like this?

    what does mean value 0xff in 0x94~0x97 ?

    Regards,
    Kim

  • Hello Brijesh, 

    I solved it.

    Now I can get image data from my sensor.

    Thanks for your advice.

    Regards,

    Kim

  • Hi Kim,

    What was the fix? Could you please help me understand?

    Regards,

    Brijesh

  • Hello Brijesh, 

    I proceeded with setting the FPD3_Mode to RAW10_Mode for my image sensor transmitting YUV422 data.

    But I couldn't get the data. Because of 0x70 (RAW10_ID).

    After setting the 0x70 register to 0x1E and tivx_raw_image was changed to vx_image in the capture code.

      

    Then, although it was not perfect, I could see the image data.

    The 0x7C register must be modified for perfect data.

    The default was Normal RAW10 Mode, and I set the 0x7C[7:6] value to 11 because it was YUV (Processing Data).

    And I was able to see the perfect image.

     

    Thank you for your continued advice.

      

    Regards,
    Kim

  • Thank you Kim for sharing details. I am closing this thread.