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.
Hi TI experts:
SDK link [here](www.ti.com/.../TDA4VEN-Q1
When I tried to use app_multi_cam demo to test csitx driver :
I confront such error:
main.c file of app_multi_cam containing my code is attathed below
Hope for your help!
BR
stream
Hi TI experts:
I opened the Debug log print , Here is more error infomation from MCU20:
BR
stream
Hi Stream,
Can you refer the below FAQ and try this implementation?
Regards,
Nikhil
Hi Nikhil :
Thank u for reply!
I reflash my sdcard and replace only vx_arm_app_multi_cam.out , vxVerifygraph passed.
But it stucks at `vxGraphParameterDequeueDoneRef` Now
I look into this function ,it stucks at `ownDataRefQueueWaitDoneRef`
Can u analyse possible cause?
Hope for your help!
BR
stream
Hi TI experts:
I try to use `vxProcessGraph` instead of using TIOVX pipeline enqueue&deque.
And vxProcessGraph will also stuck
Here is the log:
and my code attached here:
Really hope your help. This is much meaningful for me.
BR
stream
Hi :
Will `addr_translate` module impact tiovx process?
I notice that before and after I comment the following code in example.syscfg of mcu20 :
capture and csitx and display node show diffrent errors .
BR
stream
Yes, it should be required, as per system memory map, DDR_SHARED_MEM is available at 0xC0000000 location.
This essentially configures RAT on R5F, But CSITX does not require this translation, because it does not access this memory form R5F.
I will raise the bug on it.
Regards,
Brijesh
If possible, can you please print both of these addresses in tivxCsitxEnqueueFrameToDriver API in video_io\kernels\video_io\csitx\vx_csitx_target.c file with above translation enabled and share the log?
transmit_frame = tivxMemShared2PhysPtr(
(image->mem_ptr[0].shared_ptr + (uint64_t)tivxComputePatchOffset(0, 0, &image->imagepatch_addr[0U])),
TIVX_MEM_EXTERNAL);
VX_PRINT(VX_ZONE_ERROR, " CSITX: Target Buffer %x Shared Buffer %x!!!\n", transmit_frame, image->mem_ptr[0].shared_ptr);
Regards,
Brijesh
Hi Brijesh :
Thank u for explaination!!
I add the VX_PRINT but code seems not running into `tivxCsitxEnqueueFrameToDriver` which is subcall func of `tivxCsitxProcess`
Am i wrong ?
BR
stream
Hi Brijesh :
Test code attached above.
And
example.syscfg of mcu20:
/** * These arguments were used when this file was generated. They will be automatically applied on subsequent loads * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. * @cliArgs --device "J722S_TDA4VEN_TDA4AEN_AM67" --package "AMW" --part "Default" --context "main-r5fss0-0" --product "MCU_PLUS_SDK@07.03.01" * @versions {"tool":"1.20.0+3562"} */ /** * Import the modules used in this configuration. */ const dss = scripting.addModule("/drivers/dss/dss", {}, false); const dss1 = dss.addInstance(); /* Not required const gpio = scripting.addModule("/drivers/gpio/gpio", {}, false); const gpio1 = gpio.addInstance(); */ const i2c = scripting.addModule("/drivers/i2c/i2c", {}, false); const i2c1 = i2c.addInstance(); const i2c2 = i2c.addInstance(); const debug_log = scripting.addModule("/kernel/dpl/debug_log"); const mpu_armv7 = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false); const mpu_armv71 = mpu_armv7.addInstance(); const mpu_armv72 = mpu_armv7.addInstance(); const mpu_armv73 = mpu_armv7.addInstance(); const mpu_armv74 = mpu_armv7.addInstance(); const mpu_armv75 = mpu_armv7.addInstance(); const mpu_armv76 = mpu_armv7.addInstance(); const mpu_armv77 = mpu_armv7.addInstance(); const mpu_armv78 = mpu_armv7.addInstance(); const mpu_armv79 = mpu_armv7.addInstance(); const mpu_armv710 = mpu_armv7.addInstance(); const mpu_armv711 = mpu_armv7.addInstance(); const addr_translate = scripting.addModule("/kernel/dpl/addr_translate", {}, false); const addr_translate1 = addr_translate.addInstance(); /** * Write custom configuration values to the imported modules. */ dss1.$name = "CONFIG_DSS0"; dss1.selectOverlayManager = "OVR1"; dss1.selectVP = "VP1"; dss1.selectDisplayInterface = "OLDI"; dss1.oldiMapType = "OLDI_MAP_TYPE_C"; dss1.dualModeSync = "OLDI_DUALMODESYNC_DISABLE"; dss1.selectVideoPipeline = "VID1"; dss1.activeVideoPolarity = "POL_LOW"; dss1.DSS.$suggestSolution = "DSS0"; /* Not required gpio1.$name = "CONFIG_GPIO0"; gpio1.pinDir = "OUTPUT"; gpio1.GPIO.gpioPin.$assign = "MMC2_DAT0"; */ i2c1.useWakeupDomainPeripherals = false; i2c1.$name = "HDMI_I2C_CONFIG"; i2c1.I2C.$assign = "I2C0"; i2c2.$name = "CONFIG_I2C2"; i2c2.useWakeupDomainPeripherals = false; i2c2.I2C.$assign = "I2C2"; debug_log.enableSharedMemLog = false; debug_log.enableLogZoneWarning = false; debug_log.enableLogZoneError = false; debug_log.enableUartLog = false; debug_log.enableCssLog = false; debug_log.enableUartLog = true; debug_log.uartLog.$name = "CONFIG_UART1"; debug_log.uartLog.useWakeupDomainPeripherals = false; debug_log.uartLog.useMcuDomainPeripherals = true; debug_log.uartLog.MCU_UART.$assign = "MCU_USART0"; debug_log.uartLog.MCU_UART.RXD.$assign = "MCU_UART0_RXD"; debug_log.uartLog.MCU_UART.TXD.$assign = "MCU_UART0_TXD"; mpu_armv71.baseAddr = 0x0; mpu_armv71.size = 31; /* 2 GB */ mpu_armv71.attributes = "Device"; mpu_armv71.allowExecute = false; mpu_armv71.$name = "CONFIG_MPU_REGISTER"; mpu_armv72.baseAddr = 0x0; mpu_armv72.size = 15; /* 32 KB */ mpu_armv72.$name = "CONFIG_MPU_TCMA"; mpu_armv72.allowExecute = true; mpu_armv72.attributes = "NonCached"; mpu_armv73.baseAddr = 0x41010000; mpu_armv73.size = 15; /* 32 KB */ mpu_armv73.$name = "CONFIG_MPU_TCMB"; mpu_armv73.allowExecute = true; mpu_armv73.attributes = "NonCached"; mpu_armv74.baseAddr = 0x60000000; mpu_armv74.size = 26; /* 64 MB */ mpu_armv74.$name = "CONFIG_MPU_FLASH"; mpu_armv74.allowExecute = true; mpu_armv75.baseAddr = 0x79100000; mpu_armv75.size = 19; /* 512 KB */ mpu_armv75.$name = "CONFIG_MPU_MCU_MSRAM"; mpu_armv75.allowExecute = true; mpu_armv76.baseAddr = 0x80000000; mpu_armv76.size = 31; /* 2 GB */ mpu_armv76.$name = "CONFIG_MPU_DDR"; mpu_armv76.allowExecute = true; mpu_armv77.baseAddr = 0xA2000000; mpu_armv77.size = 20; mpu_armv77.$name = "LINUX_VRING"; mpu_armv77.allowExecute = false; mpu_armv77.attributes = "NonCached"; mpu_armv78.baseAddr = 0xA2100000; mpu_armv78.size = 20; mpu_armv78.allowExecute = false; mpu_armv78.$name = "RESOURCE_TABLE_AND_TRACE"; mpu_armv78.attributes = "NonCached"; mpu_armv79.baseAddr = 0xA5000000; mpu_armv79.size = 24; /* 32 MB */ mpu_armv79.allowExecute = false; mpu_armv79.$name = "RTOS_IPC_VRING"; mpu_armv79.attributes = "NonCached"; mpu_armv710.baseAddr = 0xA7000000; mpu_armv710.size = 24; mpu_armv710.allowExecute = false; mpu_armv710.$name = "TIOVX_RUN_TIME_LOGGING1"; mpu_armv710.attributes = "NonCached"; mpu_armv711.baseAddr = 0xAB000000; mpu_armv711.size = 24; mpu_armv711.allowExecute = false; mpu_armv711.$name = "TIOVX_RUN_TIME_LOGGING2"; mpu_armv711.attributes = "NonCached"; /* Not required gpio1.GPIO.$suggestSolution = "GPIO0"; */ i2c1.I2C.SCL.$suggestSolution = "I2C0_SCL"; i2c1.I2C.SDA.$suggestSolution = "I2C0_SDA"; i2c2.I2C.SCL.$suggestSolution = "GPMC0_CSn2"; i2c2.I2C.SDA.$suggestSolution = "GPMC0_CSn3"; addr_translate1.$name = "CONFIG_ADDR_TRANSLATE_REGION0"; addr_translate1.localAddr = 0xC0000000; addr_translate1.systemAddr = 0x900000000;
BR
stream
Hi Stream,
Do you see any other print from the mcu_0 core? It seems none of the prints are coming. Are you running vision_apps_init.sh script to run remote log service?
Regards,
Brijesh
Hi Brijesh :
Yes, I do run ./vision_app_init.sh before run_app_multi_cam.sh . And I did see the print from the mcu cores :
[MCU2_0] 5.500580 s: CIO: Init ... Done !!! [MCU2_0] 5.500623 s: CPU is running FreeRTOS [MCU2_0] 5.500635 s: APP: Init ... !!! [MCU2_0] 5.500646 s: SCICLIENT: Init ... !!! [MCU2_0] 5.503839 s: SCICLIENT: DMSC FW version [9.0.6--w2023.01-j722s (Kool Koa] [MCU2_0] 5.503857 s: SCICLIENT: DMSC FW revision 0x9 [MCU2_0] 5.503870 s: SCICLIENT: DMSC FW ABI revision 3.1 [MCU2_0] 5.503883 s: SCICLIENT: Init ... Done !!! [MCU2_0] 5.503895 s: MEM: Init ... !!! [MCU2_0] 5.503908 s: MEM: Created heap (DDR_LOCAL_MEM, id=0, flags=0x00000004) @ b5800000 of size 33554432 bytes !!! [MCU2_0] 5.503935 s: MEM: Init ... Done !!! [MCU2_0] 5.503946 s: IPC: Init ... !!! [MCU2_0] 5.503959 s: IPC: 4 CPUs participating in IPC !!! [MCU2_0] 5.504162 s: IPC: Waiting for HLOS to be ready ... !!! [MCU2_0] 17.987635 s: IPC: HLOS is ready !!! [MCU2_0] 17.987700 s: IPC: Init ... Done !!! [MCU2_0] 17.987719 s: APP: Syncing with 3 CPUs ... !!! [MCU2_0] 17.987739 s: APP: Syncing with 3 CPUs ... Done !!! [MCU2_0] 17.987753 s: REMOTE_SERVICE: Init ... !!! [MCU2_0] 17.988712 s: REMOTE_SERVICE: Init ... Done !!! [MCU2_0] 17.988736 s: FVID2: Init ... !!! [MCU2_0] 17.988789 s: FVID2: Init ... Done !!! [MCU2_0] 17.988824 s: VHWA: VPAC Init ... !!! [MCU2_0] 17.988879 s: SCICLIENT: Sciclient_pmSetModuleState module=219 state=2 [MCU2_0] 17.989048 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.989064 s: VHWA: LDC Init ... !!! [MCU2_0] 17.989411 s: VHWA: LDC Init ... Done !!! [MCU2_0] 17.989476 s: VHWA: MSC Init ... !!! [MCU2_0] 17.990030 s: VHWA: MSC Init ... Done !!! [MCU2_0] 17.990046 s: VHWA: VISS Init ... !!! [MCU2_0] 17.990147 s: VHWA: VISS Init ... Done !!! [MCU2_0] 17.990165 s: VHWA: VPAC Init ... Done !!! [MCU2_0] 17.990202 s: VHWA: DMPAC: Init ... !!! [MCU2_0] 17.990241 s: SCICLIENT: Sciclient_pmSetModuleState module=277 state=2 [MCU2_0] 17.990370 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.990387 s: VHWA: DOF Init ... !!! [MCU2_0] 17.990596 s: VHWA: DOF Init ... Done !!! [MCU2_0] 17.990611 s: VHWA: SDE Init ... !!! [MCU2_0] 17.990711 s: VHWA: SDE Init ... Done !!! [MCU2_0] 17.990727 s: VHWA: DMPAC: Init ... Done !!! [MCU2_0] 17.990750 s: VX_ZONE_INIT:Enabled [MCU2_0] 17.990763 s: VX_ZONE_ERROR:Enabled [MCU2_0] 17.990775 s: VX_ZONE_WARNING:Enabled [MCU2_0] 17.991294 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target MCU2-0 [MCU2_0] 17.991359 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target VPAC_LDC1 [MCU2_0] 17.991411 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target VPAC_MSC1 [MCU2_0] 17.991461 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target VPAC_MSC2 [MCU2_0] 17.991553 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target VPAC_VISS1 [MCU2_0] 17.991625 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CAPTURE1 [MCU2_0] 17.991684 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CAPTURE2 [MCU2_0] 17.991744 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CAPTURE3 [MCU2_0] 17.991805 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CAPTURE4 [MCU2_0] 17.991867 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DISPLAY1 [MCU2_0] 17.991940 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DISPLAY2 [MCU2_0] 17.991995 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CSITX [MCU2_0] 17.992048 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target CSITX2 [MCU2_0] 17.992105 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DMPAC_SDE [MCU2_0] 17.992167 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DMPAC_DOF [MCU2_0] 17.992189 s: VX_ZONE_INIT:[tivxInitLocal:136] Initialization Done !!! [MCU2_0] 17.992203 s: APP: OpenVX Target kernel init ... !!! [MCU2_0] 17.996241 s: APP: OpenVX Target kernel init ... Done !!! [MCU2_0] 17.996264 s: UDMA: Init for CSITX/CSIRX ... !!! [MCU2_0] 17.996511 s: UDMA: Init for CSITX/CSIRX ... Done !!! [MCU2_0] 17.996532 s: CSI2RX: Init ... !!! [MCU2_0] 17.996544 s: SCICLIENT: Sciclient_pmSetModuleState module=182 state=2 [MCU2_0] 17.996587 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.996602 s: SCICLIENT: Sciclient_pmSetModuleState module=247 state=2 [MCU2_0] 17.996671 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.996685 s: SCICLIENT: Sciclient_pmSetModuleState module=185 state=2 [MCU2_0] 17.996732 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.996744 s: SCICLIENT: Sciclient_pmSetModuleState module=251 state=2 [MCU2_0] 17.996788 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.996967 s: CSI2RX: Init ... Done !!! [MCU2_0] 17.996984 s: CSI2TX: Init ... !!! [MCU2_0] 17.996995 s: SCICLIENT: Sciclient_pmSetModuleState module=250 state=2 [MCU2_0] 17.997056 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.997069 s: SCICLIENT: Sciclient_pmSetModuleState module=238 state=2 [MCU2_0] 17.997120 s: SCICLIENT: Sciclient_pmSetModuleState success [MCU2_0] 17.997133 s: SCICLIENT: Sciclient_pmSetModuleClkFreq module=250 clk=3 freq=16000000 [MCU2_0] 17.997191 s: SCICLIENT: Sciclient_pmSetModuleClkFreq success [MCU2_0] 17.997205 s: SCICLIENT: Sciclient_pmSetModuleClkFreq module=250 clk=4 freq=500000000 [MCU2_0] 17.997258 s: SCICLIENT: Sciclient_pmSetModuleClkFreq success [MCU2_0] 17.997289 s: CSI2TX: Init ... Done !!! [MCU2_0] 17.997302 s: ISS: Init ... !!! [MCU2_0] 17.997319 s: IssSensor_Init ... Done !!! [MCU2_0] 17.997492 s: #stream# writing 0xf0 to deser i2caddr: 0x29 register 0x6 [MCU2_0] 17.997654 s: #stream# writing 0xf0 to deser i2caddr: 0x6b register 0x6 [MCU2_0] 17.997806 s: #stream# writing 0x12 to deser i2caddr: 0x4c register 0x1 [MCU2_0] 17.997954 s: #stream# writing 0xc0 to deser i2caddr: 0x40 register 0x0 [MCU2_0] 17.998104 s: #stream# writing 0xff to deser i2caddr: 0x29 register 0x6 [MCU2_0] 17.998251 s: #stream# writing 0xff to deser i2caddr: 0x6b register 0x6 [MCU2_0] 17.998399 s: #stream# writing 0x2 to deser i2caddr: 0x4c register 0x1 [MCU2_0] 17.998454 s: IttRemoteServer_Init ... Done !!! [MCU2_0] 17.998467 s: ISS: Init ... Done !!! [MCU2_0] 17.998480 s: VISS REMOTE SERVICE: Init ... !!! [MCU2_0] 17.998517 s: VISS REMOTE SERVICE: Init ... Done !!! [MCU2_0] 17.998531 s: APP: Init ... Done !!! [MCU2_0] 17.998544 s: APP: Run ... !!! [MCU2_0] 17.998555 s: IPC: Starting echo test ... [MCU2_0] 17.998621 s: APP: Run ... Done !!! [MCU2_0] 17.999014 s: IPC: Echo status: a530-0[.] main-r5f0-0[s] c75ss0[P] c75ss1[.] [MCU2_0] 17.999177 s: IPC: Echo status: a530-0[.] main-r5f0-0[s] c75ss0[P] c75ss1[P] [C7x_1 ] 6.035403 s: CIO: Init ... Done !!! [C7x_1 ] 6.035421 s: CPU is running FreeRTOS [C7x_1 ] 6.035433 s: APP: Init ... !!! [C7x_1 ] 6.035441 s: SCICLIENT: Init ... !!! [C7x_1 ] 6.038639 s: SCICLIENT: DMSC FW version [9.0.6--w2023.01-j722s (Kool Koa] [C7x_1 ] 6.038657 s: SCICLIENT: DMSC FW revision 0x9 [C7x_1 ] 6.038670 s: SCICLIENT: DMSC FW ABI revision 3.1 [C7x_1 ] 6.038683 s: SCICLIENT: Init ... Done !!! [C7x_1 ] 6.038693 s: UDMA: Init ... !!! [C7x_1 ] 6.038702 s: UDMA: Init ... Done !!! [C7x_1 ] 6.038713 s: MEM: Init ... !!! [C7x_1 ] 6.038724 s: MEM: Created heap (DDR_LOCAL_MEM, id=0, flags=0x00000004) @ 102000000 of size 117440512 bytes !!! [C7x_1 ] 6.038750 s: MEM: Init ... Done !!! [C7x_1 ] 6.038760 s: IPC: Init ... !!! [C7x_1 ] 6.038770 s: IPC: 4 CPUs participating in IPC !!! [C7x_1 ] 6.039085 s: IPC: Waiting for HLOS to be ready ... !!! [C7x_1 ] 17.353844 s: IPC: HLOS is ready !!! [C7x_1 ] 17.353917 s: IPC: Init ... Done !!! [C7x_1 ] 17.353930 s: APP: Syncing with 3 CPUs ... !!! [C7x_1 ] 17.987740 s: APP: Syncing with 3 CPUs ... Done !!! [C7x_1 ] 17.987757 s: REMOTE_SERVICE: Init ... !!! [C7x_1 ] 17.987890 s: REMOTE_SERVICE: Init ... Done !!! [C7x_1 ] 17.987915 s: VX_ZONE_INIT:Enabled [C7x_1 ] 17.987927 s: VX_ZONE_ERROR:Enabled [C7x_1 ] 17.987940 s: VX_ZONE_WARNING:Enabled [C7x_1 ] 17.988624 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1 [C7x_1 ] 17.988725 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_2 [C7x_1 ] 17.988881 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_3 [C7x_1 ] 17.988986 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_4 [C7x_1 ] 17.989137 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_5 [C7x_1 ] 17.989280 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_6 [C7x_1 ] 17.989421 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_7 [C7x_1 ] 17.989568 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-1_PRI_8 [C7x_1 ] 17.989639 s: VX_ZONE_INIT:[tivxInitLocal:136] Initialization Done !!! [C7x_1 ] 17.989658 s: APP: OpenVX Target kernel init ... !!! [C7x_1 ] 17.990113 s: APP: OpenVX Target kernel init ... Done !!! [C7x_1 ] 17.990131 s: APP: Init ... Done !!! [C7x_1 ] 17.990143 s: APP: Run ... !!! [C7x_1 ] 17.990153 s: IPC: Starting echo test ... [C7x_1 ] 17.990287 s: APP: Run ... Done !!! [C7x_1 ] 17.999155 s: IPC: Echo status: a530-0[.] main-r5f0-0[P] c75ss0[s] c75ss1[.] [C7x_1 ] 17.999232 s: IPC: Echo status: a530-0[.] main-r5f0-0[P] c75ss0[s] c75ss1[P] [C7x_2 ] 6.570611 s: CIO: Init ... Done !!! [C7x_2 ] 6.570629 s: CPU is running FreeRTOS [C7x_2 ] 6.570640 s: APP: Init ... !!! [C7x_2 ] 6.570649 s: SCICLIENT: Init ... !!! [C7x_2 ] 6.573845 s: SCICLIENT: DMSC FW version [9.0.6--w2023.01-j722s (Kool Koa] [C7x_2 ] 6.573884 s: SCICLIENT: DMSC FW revision 0x9 [C7x_2 ] 6.573896 s: SCICLIENT: DMSC FW ABI revision 3.1 [C7x_2 ] 6.573908 s: SCICLIENT: Init ... Done !!! [C7x_2 ] 6.573919 s: UDMA: Init ... !!! [C7x_2 ] 6.573928 s: UDMA: Init ... Done !!! [C7x_2 ] 6.573938 s: MEM: Init ... !!! [C7x_2 ] 6.573950 s: MEM: Created heap (DDR_LOCAL_MEM, id=0, flags=0x00000004) @ 112000000 of size 117440512 bytes !!! [C7x_2 ] 6.573977 s: MEM: Init ... Done !!! [C7x_2 ] 6.573986 s: IPC: Init ... !!! [C7x_2 ] 6.573997 s: IPC: 4 CPUs participating in IPC !!! [C7x_2 ] 6.574308 s: IPC: Waiting for HLOS to be ready ... !!! [C7x_2 ] 17.576028 s: IPC: HLOS is ready !!! [C7x_2 ] 17.576104 s: IPC: Init ... Done !!! [C7x_2 ] 17.576119 s: APP: Syncing with 3 CPUs ... !!! [C7x_2 ] 17.987741 s: APP: Syncing with 3 CPUs ... Done !!! [C7x_2 ] 17.987757 s: REMOTE_SERVICE: Init ... !!! [C7x_2 ] 17.988098 s: REMOTE_SERVICE: Init ... Done !!! [C7x_2 ] 17.988121 s: VX_ZONE_INIT:Enabled [C7x_2 ] 17.988133 s: VX_ZONE_ERROR:Enabled [C7x_2 ] 17.988144 s: VX_ZONE_WARNING:Enabled [C7x_2 ] 17.988908 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2 [C7x_2 ] 17.989062 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_2 [C7x_2 ] 17.989210 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_3 [C7x_2 ] 17.989349 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_4 [C7x_2 ] 17.989490 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_5 [C7x_2 ] 17.989645 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_6 [C7x_2 ] 17.989760 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_7 [C7x_2 ] 17.989873 s: VX_ZONE_INIT:[tivxPlatformCreateTargetId:116] Added target DSP_C7-2_PRI_8 [C7x_2 ] 17.989907 s: VX_ZONE_INIT:[tivxInitLocal:136] Initialization Done !!! [C7x_2 ] 17.989923 s: APP: OpenVX Target kernel init ... !!! [C7x_2 ] 17.990350 s: APP: OpenVX Target kernel init ... Done !!! [C7x_2 ] 17.990388 s: APP: Init ... Done !!! [C7x_2 ] 17.990410 s: APP: Run ... !!! [C7x_2 ] 17.990422 s: IPC: Starting echo test ... [C7x_2 ] 17.990554 s: APP: Run ... Done !!! [C7x_2 ] 17.999256 s: IPC: Echo status: a530-0[.] main-r5f0-0[P] c75ss0[.] c75ss1[s] [C7x_2 ] 17.999363 s: IPC: Echo status: a530-0[.] main-r5f0-0[P] c75ss0[P] c75ss1[s]
The part in picture I cuted out is from last part of the log from run_app_multi_cam.sh .
BR
stream
oh, why is then the prints from R5F not coming? Can you please then put this print in the caller of this API tivxCsitxEnqueueFrameToDriver?
Regards,
Brijesh
Hi Brijesh :
Sorry, I got the rough conclusion. The truth is :
Code runs into the tivxCsitxEnqueueFrameToDriver ,but the varible `prms->numOfInstUsed ` is 0 , so loop end directly.
code :
log :
BR
stream
Hi Brijesh :
I add some log print in func tivxCsitxSetCreateParams like this :
the result :
It seems
BR
stream
Hi :
csitx_config_target_ptr = tivxMemShared2TargetPtr(&obj_desc->mem_ptr);
I print the ptr addr of this :
code refer:
BR
stream
Hi TI experts :
Any progress in this issue ? Looking forwards to your reply.
BR
stream
Hi stream,
That's very strange that number of instances is set 0. It should not be if it is set correctly. Let me check the driver code in SDK9.2 and get back to you.
Regards,
Brijesh
Hi Brijesh:
I print the ptr addr of this :
Can you help check the result of `tivxMemShared2TargetPtr` in the log?
BR
stream
Hi stream,
ok, i see below comment in ti-processor-sdk-rtos-j722s-evm-09_02_00_05/vision_apps/platform/j722s/rtos/gen_linker_mem_map.py. Most likely, the buffer space is mapped to 0x900000000 higher memory and it is mapped to 0xC0000000 location in mcu2_0. So when mcu2_0 would like to access it will access using 0xC0000000 location and so in the above print, csitx_config_target_ptr is correct.
# Shared memory for DMA Buf FD carveout
ddr_shared_mem_addr = 0xC0000000; # This will be the virtual address used for R5F's / C7X's
ddr_shared_mem_size = 512*MB;
Buffer address conversion also seems to be correct. This API flow convers local address starting from 0xC0000000 to physical address..
tivxMemShared2PhysPtr -> appMemShared2PhysPtr -> appTarget2SharedConversion
Can you please somehow print the buffer addresses in the CSITX node to see if this conversion is happening correctly?
Regards,
Brijesh
Hi Brijesh :
Thank u for the validation.
I traced
csitx_config = vxCreateUserDataObject(obj->context, "tivx_csitx_params_t", sizeof(tivx_csitx_params_t), &local_csitx_config);
by adding the print log in func `vxCopyUserDataObject() ` of `vx_user_data_object.c`
and this is the result log:
Can you please tell me if there is anywhere else I can add the print log to trace the conversion of buffer addresses.
I notice that :
- start_ptr is from mem_ptr. host_ptr , it write local_csitx_config into the shared mem of host_ptr addr
and I cannot find the `mem_ptr.shared_ptr` getting value. csitx_config_target_ptr is get the value from mem_ptr.shared_ptr directly.
- if the conversion is correctly , I debug with lauterbach tools , the address in (tivx_csitx_params_t *)0xc0001000 (csitx_config_target_ptr ) is totaly empty. Seems ptr from shared_ptr is wrong itself.
I wish the infomation can help you debug
Looking forwars to your reply
BR
stream
Hi stream,
Can you please tell me if there is anywhere else I can add the print log to trace the conversion of buffer addresses.
But this copy happens on the A72 core, ie on Linux user space.. isn't it? That's why it needs to use host_ptr, because this buffer needs to be mapped in the Linux memory/process space.. This is different from the address conversion that is happening on the R5F core.
and I cannot find the `mem_ptr.shared_ptr` getting value. csitx_config_target_ptr is get the value from mem_ptr.shared_ptr directly.
Shared_ptr is initialized in this API ownAllocReferenceBufferGeneric, when memory for the user data object is allocated.. That's typically set the physical memory location.
- if the conversion is correctly , I debug with lauterbach tools , the address in (tivx_csitx_params_t *)0xc0001000 (csitx_config_target_ptr ) is totaly empty. Seems ptr from shared_ptr is wrong itself.
But does laauterback access the memory via RAT? I think it doesnot. Instead of looking at this locaiton, you can check variables at 0x900001000 location, which is the corresponding mapped address.
Regards,
Brijesh
Hi Brijesh :
Thank u , I will check this next day .
you can check variables at 0x900001000 location, which is the corresponding mapped address
BR
stream
Hi Brijesh:
Sorry for the delay.
1. I checked the addr of mem_ptr-> host_ptr where local config just copied into in `vxCopyUserDataObject` at A53 core side
I can get the correct value which I set, you can also see the log which records the host_ptr and shared_ptr and according phy_ptr
reference code :
2. Meanwhile I track the shared_ptr at R5f core side in lauterbach , both 0xc03f6000 and 0x9003f6000 (which is the conversion of 0xc03f6000) is empty
Looking forwards to your reply
BR
stream
Hi stream,
Can you please check if the cache operation is properly performed on this user data object at the offset 0xc03f6000? I am wondering if this is some cache issue. Is it possible to check the physical location from some other core? Lets say C7x can access 0x9003f6000 location directly? Can we check if it has some valid contents from C7x?
Regards,
Brijesh
Hi Brijesh :
Sorry, How to check the cache operation is properly performed ?
Can you please check if the cache operation is properly performed on this user data object at the offset 0xc03f6000?
BR
stream
Hi Stream,
I meant, after copying the user data object, is cache written back? or before accessing user data object on R5F side, is cache invalidated?
Regards,
Brijesh
Hi Brijesh :
I think it's harder for me to look into this issue further now.
Let's make it simple.
- TDA4VEN Demo board
- Raw version LINUX&RTOS SDK download from here
Add csitx code to main.c of app_multi_cam demo and didnot modify any other files in SDK
/* * * Copyright (c) 2020 Texas Instruments Incorporated * * All rights reserved not granted herein. * * Limited License. * * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive * license under copyrights and patents it now or hereafter owns or controls to make, * have made, use, import, offer to sell and sell ("Utilize") this software subject to the * terms herein. With respect to the foregoing patent license, such license is granted * solely to the extent that any such patent is necessary to Utilize the software alone. * The patent license shall not apply to any combinations which include this software, * other than combinations with devices manufactured by or for TI ("TI Devices"). * No hardware patent is licensed hereunder. * * Redistributions must preserve existing copyright notices and reproduce this license * (including the above copyright notice and the disclaimer and (if applicable) source * code license limitations below) in the documentation and/or other materials provided * with the distribution * * Redistribution and use in binary form, without modification, are permitted provided * that the following conditions are met: * * * No reverse engineering, decompilation, or disassembly of this software is * permitted with respect to any software provided in binary form. * * * any redistribution and use are licensed by TI for use only with TI Devices. * * * Nothing shall obligate TI to provide you with source code for the software * licensed and provided to you in object code. * * If software source code is provided to you, modification and redistribution of the * source code are permitted provided that the following conditions are met: * * * any redistribution and use of the source code, including any resulting derivative * works, are licensed by TI for use only with TI Devices. * * * any redistribution and use of any object code compiled from the source code * and any resulting derivative works, are licensed by TI for use only with TI Devices. * * Neither the name of Texas Instruments Incorporated nor the names of its suppliers * * may be used to endorse or promote products derived from this software without * specific prior written permission. * * DISCLAIMER. * * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include <utils/draw2d/include/draw2d.h> #include <utils/perf_stats/include/app_perf_stats.h> #include <utils/console_io/include/app_get.h> #include <utils/grpx/include/app_grpx.h> #include <utils/hwa/include/app_hwa_api.h> #include <VX/vx_khr_pipelining.h> #include <TI/video_io_kernels.h> #include <TI/video_io_csitx.h> #include "app_common.h" #include "app_sensor_module.h" #include "app_capture_module.h" #include "app_obj_arr_split_module.h" #include "app_viss_module.h" #include "app_aewb_module.h" #include "app_ldc_module.h" #include "app_img_mosaic_module.h" #include "app_display_module.h" #include "app_test.h" #define CAPTURE_BUFFER_Q_DEPTH (4) #define APP_BUFFER_Q_DEPTH (4) #define APP_PIPELINE_DEPTH (7) //#define APP_TIVX_LOG_RT_ENABLE #define NUM_CHANNELS (1U)//(4U) #define CSITX_LANE_SPEED_MBPS (300U) typedef struct { SensorObj sensorObj; CaptureObj captureObj; ObjArrSplitObj objArrSplitObj; VISSObj vissObj; AEWBObj aewbObj; LDCObj ldcObj; VISSObj vissObj1; AEWBObj aewbObj1; LDCObj ldcObj1; ImgMosaicObj imgMosaicObj; DisplayObj displayObj; vx_char output_file_path[APP_MAX_FILE_PATH]; /* OpenVX references */ vx_context context; vx_graph graph; vx_graph csitx_graph; vx_image csitx_image_exemplar; vx_int32 en_out_img_write; vx_int32 test_mode; vx_uint32 is_interactive; vx_uint32 num_frames_to_run; vx_uint32 num_frames_to_write; vx_uint32 num_frames_to_skip; tivx_task task; vx_uint32 stop_task; vx_uint32 stop_task_done; app_perf_point_t total_perf; app_perf_point_t fileio_perf; app_perf_point_t draw_perf; int32_t enable_ldc; int32_t enable_viss; int32_t enable_split_graph; int32_t enable_aewb; int32_t enable_mosaic; int32_t pipeline; int32_t enqueueCnt; int32_t dequeueCnt; int32_t write_file; vx_uint32 enable_configure_hwa_freq; vx_uint32 hwa_freq_config; vx_uint32 bypass_split_graph; } AppObj; AppObj gAppObj; static void app_parse_cmd_line_args(AppObj *obj, vx_int32 argc, vx_char *argv[]); static vx_status app_init(AppObj *obj); static void app_deinit(AppObj *obj); static vx_status app_create_graph(AppObj *obj); static vx_status app_verify_graph(AppObj *obj); static vx_status app_run_graph(AppObj *obj); static vx_status app_run_graph_interactive(AppObj *obj); static void app_delete_graph(AppObj *obj); static void app_default_param_set(AppObj *obj); static void app_update_param_set(AppObj *obj); static void app_pipeline_params_defaults(AppObj *obj); static void add_graph_parameter_by_node_index(vx_graph graph, vx_node node, vx_uint32 node_parameter_index); static vx_int32 calc_grid_size(vx_uint32 ch); static void set_img_mosaic_params(ImgMosaicObj *imgMosaicObj, vx_uint32 in_width, vx_uint32 in_height, vx_int32 numCh, ObjArrSplitObj *objArrSplitObj, int32_t enable_split_graph); static void app_draw_graphics(Draw2D_Handle *handle, Draw2D_BufInfo *draw2dBufInfo, uint32_t update_type); static void app_show_usage(vx_int32 argc, vx_char* argv[]) { printf("\n"); printf(" Camera Demo - (c) Texas Instruments 2020\n"); printf(" ========================================================\n"); printf("\n"); printf(" Usage,\n"); printf(" %s --cfg <config file>\n", argv[0]); printf("\n"); } static char menu[] = { "\n" "\n =========================" "\n Demo : Camera Demo" "\n =========================" "\n" "\n s: Save CSIx, VISS and LDC outputs" "\n" "\n p: Print performance statistics" "\n" "\n x: Exit" "\n" "\n Enter Choice: " }; static void app_run_task(void *app_var) { AppObj *obj = (AppObj *)app_var; vx_status status = VX_SUCCESS; while((!obj->stop_task) && (status == VX_SUCCESS)) { status = app_run_graph(obj); } obj->stop_task_done = 1; } static int32_t app_run_task_create(AppObj *obj) { tivx_task_create_params_t params; vx_status status; tivxTaskSetDefaultCreateParams(¶ms); params.task_main = app_run_task; params.app_var = obj; obj->stop_task_done = 0; obj->stop_task = 0; status = tivxTaskCreate(&obj->task, ¶ms); return status; } static void app_run_task_delete(AppObj *obj) { while(obj->stop_task_done==0) { tivxTaskWaitMsecs(100); } tivxTaskDelete(&obj->task); } 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 == VX_FAILURE) { printf("app_tidl: ERROR: Unable to create task\n"); } else { appPerfStatsResetAll(); while(!done) { printf(menu); ch = getchar(); printf("\n"); switch(ch) { case 'p': appPerfStatsPrintAll(); status = tivx_utils_graph_perf_print(obj->graph); appPerfPointPrint(&obj->fileio_perf); appPerfPointPrint(&obj->total_perf); printf("\n"); appPerfPointPrintFPS(&obj->total_perf); appPerfPointReset(&obj->total_perf); printf("\n"); vx_reference refs[1]; refs[0] = (vx_reference)obj->captureObj.raw_image_arr[0]; if (status == VX_SUCCESS) { status = tivxNodeSendCommand(obj->captureObj.node, 0u, TIVX_CAPTURE_PRINT_STATISTICS, refs, 1u); } break; case 'e': perf_arr[0] = &obj->total_perf; fp = appPerfStatsExportOpenFile(".", "basic_demos_app_multi_cam"); if (NULL != fp) { appPerfStatsExportAll(fp, perf_arr, 1); if (status == VX_SUCCESS) { status = tivx_utils_graph_perf_export(fp, obj->graph); } appPerfStatsExportCloseFile(fp); appPerfStatsResetAll(); } else { printf("fp is null\n"); } break; case 's': obj->write_file = 1; break; case 'x': obj->stop_task = 1; done = 1; break; } } app_run_task_delete(obj); } return status; } static void app_set_cfg_default(AppObj *obj) { snprintf(obj->captureObj.output_file_path,APP_MAX_FILE_PATH, "."); snprintf(obj->vissObj.output_file_path,APP_MAX_FILE_PATH, "."); snprintf(obj->vissObj1.output_file_path,APP_MAX_FILE_PATH, "."); snprintf(obj->ldcObj.output_file_path,APP_MAX_FILE_PATH, "."); obj->captureObj.en_out_capture_write = 0; obj->vissObj.en_out_viss_write = 0; obj->vissObj1.en_out_viss_write = 0; obj->ldcObj.en_out_ldc_write = 0; obj->ldcObj1.en_out_ldc_write = 0; obj->num_frames_to_write = 0; obj->num_frames_to_skip = 0; obj->objArrSplitObj.num_outputs = 2; obj->objArrSplitObj.output0_num_elements = 0; obj->objArrSplitObj.output1_num_elements = 0; obj->objArrSplitObj.output2_num_elements = 0; obj->objArrSplitObj.output3_num_elements = 0; } static void app_parse_cfg_file(AppObj *obj, vx_char *cfg_file_name) { FILE *fp = fopen(cfg_file_name, "r"); vx_char line_str[1024]; vx_char *token; if(fp==NULL) { printf("# ERROR: Unable to open config file [%s]\n", cfg_file_name); exit(0); } while(fgets(line_str, sizeof(line_str), fp)!=NULL) { vx_char s[]=" \t"; if (strchr(line_str, '#')) { continue; } /* get the first token */ token = strtok(line_str, s); if(token != NULL) { if(strcmp(token, "sensor_index")==0) { token = strtok(NULL, s); if(token != NULL) { obj->sensorObj.sensor_index = atoi(token); } } else if(strcmp(token, "num_frames_to_run")==0) { token = strtok(NULL, s); if(token != NULL) { obj->num_frames_to_run = atoi(token); } } else if(strcmp(token, "enable_error_detection")==0) { token = strtok(NULL, s); if(token != NULL) { obj->captureObj.enable_error_detection = atoi(token); } } else if(strcmp(token, "enable_configure_hwa_freq")==0) { token = strtok(NULL, s); if(token != NULL) { obj->enable_configure_hwa_freq = atoi(token); } } else if(strcmp(token, "hwa_freq_config")==0) { token = strtok(NULL, s); if(token != NULL) { obj->hwa_freq_config = atoi(token); } } else if(strcmp(token, "enable_ldc")==0) { token = strtok(NULL, s); if(token != NULL) { obj->sensorObj.enable_ldc = atoi(token); if(obj->sensorObj.enable_ldc > 1) obj->sensorObj.enable_ldc = 1; } } else if(strcmp(token, "en_out_img_write")==0) { token = strtok(NULL, s); if(token != NULL) { obj->en_out_img_write = atoi(token); if(obj->en_out_img_write > 1) obj->en_out_img_write = 1; } } else if(strcmp(token, "en_out_capture_write")==0) { token = strtok(NULL, s); if(token != NULL) { obj->captureObj.en_out_capture_write = atoi(token); if(obj->captureObj.en_out_capture_write > 1) obj->captureObj.en_out_capture_write = 1; } } else if(strcmp(token, "en_out_viss_write")==0) { token = strtok(NULL, s); if(token != NULL) { obj->vissObj.en_out_viss_write = atoi(token); if(obj->vissObj.en_out_viss_write > 1) obj->vissObj.en_out_viss_write = 1; } } else if(strcmp(token, "en_out_ldc_write")==0) { token = strtok(NULL, s); if(token != NULL) { obj->ldcObj.en_out_ldc_write = atoi(token); if(obj->ldcObj.en_out_ldc_write > 1) obj->ldcObj.en_out_ldc_write = 1; } } else if(strcmp(token, "output_file_path")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; strcpy(obj->captureObj.output_file_path, token); strcpy(obj->vissObj.output_file_path, token); strcpy(obj->vissObj1.output_file_path, token); strcpy(obj->ldcObj.output_file_path, token); strcpy(obj->ldcObj1.output_file_path, token); strcpy(obj->output_file_path, token); } } else if(strcmp(token, "display_option")==0) { token = strtok(NULL, s); if(token != NULL) { obj->displayObj.display_option = atoi(token); if(obj->displayObj.display_option > 1) obj->displayObj.display_option = 1; } } else if(strcmp(token, "is_interactive")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->is_interactive = atoi(token); if(obj->is_interactive > 1) { obj->is_interactive = 1; } } obj->sensorObj.is_interactive = obj->is_interactive; } else if(strcmp(token, "bypass_split_graph")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->bypass_split_graph = atoi(token); if(obj->bypass_split_graph > 1) { obj->bypass_split_graph = 1; } } } else /* num_cameras_enabled from cfg file is ignored Instead channel_mask is read. num_cameras_enabled = number of 1 bits in mask For e.g. channel_mask = 15 (0x0F) indicates that first 4 cameras are enabled */ if(strcmp(token, "channel_mask")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->sensorObj.ch_mask = atoi(token); } } else if(strcmp(token, "usecase_option")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->sensorObj.usecase_option = atoi(token); } } else if(strcmp(token, "num_frames_to_write")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->num_frames_to_write = atoi(token); } } else if(strcmp(token, "num_frames_to_skip")==0) { token = strtok(NULL, s); if(token != NULL) { token[strlen(token)-1]=0; obj->num_frames_to_skip = atoi(token); } } else if(strcmp(token, "test_mode")==0) { token = strtok(NULL, s); if(token != NULL) { obj->test_mode = atoi(token); obj->captureObj.test_mode = atoi(token); } } } } fclose(fp); } static void app_parse_cmd_line_args(AppObj *obj, vx_int32 argc, vx_char *argv[]) { vx_int32 i; vx_int16 num_test_cams = 0xFF, sensor_override = 0xFF; vx_bool set_test_mode = vx_false_e; app_set_cfg_default(obj); if(argc==1) { app_show_usage(argc, argv); exit(0); } 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]); } else if(strcmp(argv[i], "--help")==0) { app_show_usage(argc, argv); exit(0); } else if(strcmp(argv[i], "--test")==0) { set_test_mode = vx_true_e; // check to see if there is another argument following --test if (argc > i+1) { num_test_cams = atoi(argv[i+1]); // increment i again to avoid this arg i++; } } else if(strcmp(argv[i], "--sensor")==0) { // check to see if there is another argument following --sensor if (argc > i+1) { sensor_override = atoi(argv[i+1]); // increment i again to avoid this arg i++; } } } if (set_test_mode == vx_true_e) { obj->test_mode = 1; obj->captureObj.test_mode = 1; obj->is_interactive = 0; obj->bypass_split_graph = 0; obj->enable_configure_hwa_freq = 0; obj->hwa_freq_config = 0; obj->sensorObj.is_interactive = 0; // set the number of test cams from cmd line if (num_test_cams != 0xFF) { obj->sensorObj.num_cameras_enabled = num_test_cams; } if (sensor_override != 0xFF) { obj->sensorObj.sensor_index = sensor_override; } } return; } vx_int32 app_multi_cam_main(vx_int32 argc, vx_char* argv[]) { vx_status status = VX_SUCCESS; AppObj *obj = &gAppObj; /*Optional parameter setting*/ app_default_param_set(obj); /*Config parameter reading*/ app_parse_cmd_line_args(obj, argc, argv); /* Querry sensor parameters */ status = app_querry_sensor(&obj->sensorObj); if(1 == obj->sensorObj.sensor_out_format) { printf("YUV Input selected. VISS, AEWB and Mosaic nodes will be bypassed. \n"); obj->enable_viss = 0; obj->enable_split_graph = 0; obj->enable_aewb = 0; obj->enable_mosaic = 0; } else { obj->enable_viss = 1; obj->enable_split_graph = 1; obj->enable_aewb = 1; obj->enable_mosaic = 1; } /*Update of parameters are config file read*/ app_update_param_set(obj); if (status == VX_SUCCESS) { status = app_init(obj); } if(status == VX_SUCCESS) { APP_PRINTF("App Init Done! \n"); status = app_create_graph(obj); if(status == VX_SUCCESS) { APP_PRINTF("App Create Graph Done! \n"); status = app_verify_graph(obj); if(status == VX_SUCCESS) { APP_PRINTF("App Verify Graph Done! \n"); if (status == VX_SUCCESS) { APP_PRINTF("App Send Error Frame Done! \n"); if(obj->is_interactive) { status = app_run_graph_interactive(obj); } else { status = app_run_graph(obj); } } } } APP_PRINTF("App Run Graph Done! \n"); } app_delete_graph(obj); APP_PRINTF("App Delete Graph Done! \n"); app_deinit(obj); APP_PRINTF("App De-init Done! \n"); if(obj->test_mode == 1) { if((vx_false_e == test_result) || (status != VX_SUCCESS)) { printf("\n\nTEST FAILED\n\n"); print_new_checksum_structs(); status = (status == VX_SUCCESS) ? VX_FAILURE : status; } else { printf("\n\nTEST PASSED\n\n"); } } return status; } static vx_status app_init(AppObj *obj) { vx_status status = VX_SUCCESS; app_grpx_init_prms_t grpx_prms; if (1U == obj->enable_configure_hwa_freq) { APP_PRINTF("Configuring VPAC frequency!\n"); if (0U == obj->hwa_freq_config) { APP_PRINTF("Configuring VPAC frequency to 650 MHz and DMPAC to 520 MHz!\n"); status = appVhwaConfigureFreq(APP_HWA_CONFIGURE_FREQ_VPAC_650_DMPAC_520); APP_PRINTF("Configuring VPAC frequency done!\n"); } else if (1U == obj->hwa_freq_config) { APP_PRINTF("Configuring VPAC frequency to 720 MHz and DMPAC to 480 MHz!\n"); status = appVhwaConfigureFreq(APP_HWA_CONFIGURE_FREQ_VPAC_720_DMPAC_480); APP_PRINTF("Configuring VPAC frequency done!\n"); } else { APP_PRINTF("Invalid option for VPAC frequency configuration!\n"); } } if (status == VX_SUCCESS) { /* Create OpenVx Context */ obj->context = vxCreateContext(); status = vxGetStatus((vx_reference)obj->context); APP_PRINTF("Creating context done!\n"); } if (status == VX_SUCCESS) { tivxHwaLoadKernels(obj->context); tivxExtLoadKernels(obj->context); tivxVideoIOLoadKernels(obj->context); tivxImagingLoadKernels(obj->context); tivxFileIOLoadKernels(obj->context); APP_PRINTF("Kernel loading done!\n"); } /* Initialize modules */ if (status == VX_SUCCESS) { app_init_sensor(&obj->sensorObj, "sensor_obj"); } if (status == VX_SUCCESS) { APP_PRINTF("Sensor init done!\n"); status = app_init_capture(obj->context, &obj->captureObj, &obj->sensorObj, "capture_obj", CAPTURE_BUFFER_Q_DEPTH); } if( (1 == obj->enable_split_graph) && (status == VX_SUCCESS) ) { obj->objArrSplitObj.input_arr = obj->captureObj.raw_image_arr[0]; APP_PRINTF("Obj arr splitter init done!\n"); status = app_init_obj_arr_split(obj->context, &obj->objArrSplitObj, "objArrSplit_obj"); } if((1 == obj->enable_viss) && (status == VX_SUCCESS)) { status = app_init_viss(obj->context, &obj->vissObj, &obj->sensorObj, "viss_obj", obj->objArrSplitObj.output0_num_elements); APP_PRINTF("VISS init done!\n"); } if((1 == obj->enable_aewb) && (status == VX_SUCCESS)) { status = app_init_aewb(obj->context, &obj->aewbObj, &obj->sensorObj, "aewb_obj", 0, obj->objArrSplitObj.output0_num_elements); APP_PRINTF("AEWB init done!\n"); } if((obj->sensorObj.enable_ldc == 1) && (status == VX_SUCCESS)) { status = app_init_ldc(obj->context, &obj->ldcObj, &obj->sensorObj, "ldc_obj", obj->objArrSplitObj.output0_num_elements); APP_PRINTF("LDC init done!\n"); } if((1 == obj->enable_split_graph) && (status == VX_SUCCESS)) { status = app_init_viss(obj->context, &obj->vissObj1, &obj->sensorObj, "viss_obj1", obj->objArrSplitObj.output1_num_elements); APP_PRINTF("VISS init done!\n"); if((1 == obj->enable_aewb) && (status == VX_SUCCESS)) { status = app_init_aewb(obj->context, &obj->aewbObj1, &obj->sensorObj, "aewb_obj", obj->objArrSplitObj.output0_num_elements, obj->objArrSplitObj.output1_num_elements); APP_PRINTF("AEWB init done!\n"); } if((obj->sensorObj.enable_ldc == 1) && (status == VX_SUCCESS)) { status = app_init_ldc(obj->context, &obj->ldcObj1, &obj->sensorObj, "ldc_obj",obj->objArrSplitObj.output1_num_elements); APP_PRINTF("LDC init done!\n"); } } if((obj->enable_mosaic == 1) && (status == VX_SUCCESS)) { status = app_init_img_mosaic(obj->context, &obj->imgMosaicObj, "img_mosaic_obj", APP_BUFFER_Q_DEPTH); APP_PRINTF("Img Mosaic init done!\n"); } if (status == VX_SUCCESS) { status = app_init_display(obj->context, &obj->displayObj, "display_obj"); APP_PRINTF("Display init done!\n"); } appGrpxInitParamsInit(&grpx_prms, obj->context); grpx_prms.draw_callback = app_draw_graphics; appGrpxInit(&grpx_prms); appPerfPointSetName(&obj->total_perf , "TOTAL"); appPerfPointSetName(&obj->fileio_perf, "FILEIO"); return status; } static void app_deinit(AppObj *obj) { app_deinit_sensor(&obj->sensorObj); APP_PRINTF("Sensor deinit done!\n"); app_deinit_capture(&obj->captureObj, CAPTURE_BUFFER_Q_DEPTH); APP_PRINTF("Capture deinit done!\n"); if(1 == obj->enable_split_graph) { app_deinit_obj_arr_split(&obj->objArrSplitObj); APP_PRINTF("Object array splitter deinit done!\n"); } if(1 == obj->enable_viss) { app_deinit_viss(&obj->vissObj); APP_PRINTF("VISS deinit done!\n"); } if(1 == obj->enable_aewb) { app_deinit_aewb(&obj->aewbObj); APP_PRINTF("AEWB deinit done!\n"); } if(obj->sensorObj.enable_ldc == 1) { app_deinit_ldc(&obj->ldcObj); APP_PRINTF("LDC deinit done!\n"); } if(1 == obj->enable_split_graph) { app_deinit_viss(&obj->vissObj1); APP_PRINTF("VISS deinit done!\n"); if(1 == obj->enable_aewb) { app_deinit_aewb(&obj->aewbObj1); APP_PRINTF("AEWB deinit done!\n"); } if(obj->sensorObj.enable_ldc == 1) { app_deinit_ldc(&obj->ldcObj1); APP_PRINTF("LDC deinit done!\n"); } } if(obj->enable_mosaic == 1) { app_deinit_img_mosaic(&obj->imgMosaicObj, APP_BUFFER_Q_DEPTH); APP_PRINTF("Img Mosaic deinit done!\n"); } app_deinit_display(&obj->displayObj); APP_PRINTF("Display deinit done!\n"); appGrpxDeInit(); tivxHwaUnLoadKernels(obj->context); tivxExtUnLoadKernels(obj->context); tivxVideoIOUnLoadKernels(obj->context); tivxImagingUnLoadKernels(obj->context); tivxFileIOUnLoadKernels(obj->context); APP_PRINTF("Kernels unload done!\n"); vxReleaseContext(&obj->context); APP_PRINTF("Release context done!\n"); } static void app_delete_graph(AppObj *obj) { #ifdef APP_TIVX_LOG_RT_ENABLE tivxLogRtTraceExportToFile("app_multicam.bin"); tivxLogRtTraceDisable(obj->graph); #endif app_delete_capture(&obj->captureObj); APP_PRINTF("Capture delete done!\n"); if(1 == obj->enable_split_graph) { app_delete_obj_arr_split(&obj->objArrSplitObj); APP_PRINTF("Object array splitter delete done!\n"); } app_delete_viss(&obj->vissObj); APP_PRINTF("VISS delete done!\n"); app_delete_aewb(&obj->aewbObj); APP_PRINTF("AEWB delete done!\n"); if(1 == obj->enable_split_graph) { app_delete_viss(&obj->vissObj1); APP_PRINTF("VISS delete done!\n"); app_delete_aewb(&obj->aewbObj1); APP_PRINTF("AEWB delete done!\n"); } if(obj->sensorObj.enable_ldc == 1) { app_delete_ldc(&obj->ldcObj); APP_PRINTF("LDC delete done!\n"); if(1 == obj->enable_split_graph) { app_delete_ldc(&obj->ldcObj1); APP_PRINTF("LDC delete done!\n"); } } app_delete_img_mosaic(&obj->imgMosaicObj); APP_PRINTF("Img Mosaic delete done!\n"); app_delete_display(&obj->displayObj); APP_PRINTF("Display delete done!\n"); vxReleaseGraph(&obj->graph); APP_PRINTF("Graph delete done!\n"); } #define CSI_REF static vx_status app_create_graph(AppObj *obj) { vx_status status = VX_SUCCESS; vx_graph_parameter_queue_params_t graph_parameters_queue_params_list[2] = {0}; vx_int32 graph_parameter_index; #ifdef CSI_REF //add for CsiTx reference begin obj->csitx_graph = vxCreateGraph(obj->context); status = vxGetStatus((vx_reference)obj->csitx_graph); if (status == VX_SUCCESS) { APP_PRINTF("CsiTx create done!\n"); } //initial for CsiTx tivx_csitx_params_t local_csitx_config; vx_graph_parameter_queue_params_t csitx_graph_parameters_queue_params_list[1]; vx_user_data_object csitx_config; vx_object_array tx_frame = 0; vx_node csitx_node = 0; uint32_t loopCnt, loop_id; vx_pixel_value_t value; value.YUV[0] = 127; value.YUV[1] = 127; value.YUV[2] = 127; /* allocate Input and Output refs*/ obj->csitx_image_exemplar = vxCreateUniformImage(obj->context, 1920, 1080, VX_DF_IMAGE_UYVY, &value); // obj->csitx_image_exemplar = vxCreateImage(obj->context, 1920, 1080, VX_DF_IMAGE_UYVY); status = vxGetStatus((vx_reference)(obj->csitx_image_exemplar)); if(status == VX_SUCCESS) { printf("[CsiTx-MODULE] - create UYVY image object done! time: %s\n", __TIME__); } tx_frame = vxCreateObjectArray(obj->context, (vx_reference)(obj->csitx_image_exemplar), NUM_CHANNELS); status = vxGetStatus((vx_reference)tx_frame); if(status == VX_SUCCESS) { printf("[CsiTx_MODULE] - create Array object done! \n"); } vxReleaseImage(&(obj->csitx_image_exemplar)); printf("Initializing Transmit Buffers Done.\n"); /* CSITX Config initialization */ tivx_csitx_params_init(&local_csitx_config); local_csitx_config.numInst = 1U; local_csitx_config.numCh = NUM_CHANNELS; local_csitx_config.instId[0U] = 0; local_csitx_config.instCfg[0U].rxCompEnable = (uint32_t)vx_true_e; local_csitx_config.instCfg[0U].rxv1p3MapEnable = (uint32_t)vx_true_e; local_csitx_config.instCfg[0U].laneBandSpeed = TIVX_CSITX_LANE_BAND_SPEED_240_TO_320_MBPS; local_csitx_config.instCfg[0U].laneSpeedMbps = CSITX_LANE_SPEED_MBPS; local_csitx_config.instCfg[0U].numDataLanes = 4U; for (loopCnt = 0U; loopCnt < local_csitx_config.instCfg[0U].numDataLanes; loopCnt++) { local_csitx_config.instCfg[0U].lanePolarityCtrl[loopCnt] = 0u; } for (loopCnt = 0U; loopCnt < NUM_CHANNELS; loopCnt++) { local_csitx_config.chVcNum[loopCnt] = loopCnt; local_csitx_config.chInstMap[loopCnt] = 0; } csitx_config = vxCreateUserDataObject(obj->context, "tivx_csitx_params_t", sizeof(tivx_csitx_params_t), &local_csitx_config); status = vxGetStatus((vx_reference)csitx_config); if(status == VX_SUCCESS) { printf("[CsiTx_MODULE] - create capture config object done! \n"); } csitx_node = tivxCsitxNode(obj->csitx_graph, csitx_config, tx_frame); status = vxGetStatus((vx_reference)csitx_node); if(status == VX_SUCCESS) { printf("[CsiTx_MODULE] - create CsiTx node done! \n"); status = vxSetNodeTarget(csitx_node, VX_TARGET_STRING, TIVX_TARGET_CSITX); if(status == VX_SUCCESS) { printf("[CsiTx_MODULE] - Set Node target done! \n"); } } /* input @ node index 0, becomes csitx_graph parameter 1 */ add_graph_parameter_by_node_index(obj->csitx_graph, csitx_node, 1); /* set csitx_graph schedule config such that csitx_graph parameter @ index 0 and 1 are enqueuable */ csitx_graph_parameters_queue_params_list[0].graph_parameter_index = 0; csitx_graph_parameters_queue_params_list[0].refs_list_size = NUM_CHANNELS; csitx_graph_parameters_queue_params_list[0].refs_list = (vx_reference*)&(tx_frame); /* Schedule mode auto is used, here we dont need to call vxScheduleGraph * Graph gets scheduled automatically as refs are enqueued to it */ status = vxSetGraphScheduleConfig(obj->csitx_graph, VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO, 1, csitx_graph_parameters_queue_params_list ); if (status == VX_SUCCESS) { printf("[CsiTx_MODULE] - Set Schedule config done! \n"); } status = vxVerifyGraph(obj->csitx_graph); if(status == VX_SUCCESS) { printf("[CsiTx_MODULE] - Graph verify done!\n"); } /* Now enqueue a buffer to trigger csitx_graph scheduling */ status = vxGraphParameterEnqueueReadyRef(obj->csitx_graph, 0, (vx_reference*)&tx_frame, 1); printf("[CsiTx_MODULE] Enqueue result: %d\n", status); /* wait for csitx_graph instances to complete, schedule again */ /* loop_id limit is loop_count + no.of capture buffers - num.of pipeup capture buffers*/ for(loop_id=0; loop_id < 30000 ; loop_id++) { uint32_t num_refs; vx_object_array transmitted_frames = NULL; /* Get tramsnitted frame reference, waits until a reference is available */ printf("[CsiTx_MODULE] Ready to Dequeue %d\n", loop_id); status = vxGraphParameterDequeueDoneRef(obj->csitx_graph, 0, (vx_reference*)&transmitted_frames, 1, &num_refs); printf("[CsiTx_MODULE] #stream# Dequeue result: %d, %d, loop_id: %d\n", status, VX_SUCCESS, loop_id); vxGraphParameterEnqueueReadyRef(obj->csitx_graph, 0, (vx_reference*)&transmitted_frames, 1); } /* ensure all csitx_graph processing is complete */ vxWaitGraph(obj->csitx_graph); vxReleaseNode(&csitx_node); // vxReleaseObjectArray(&tx_frame); vxReleaseUserDataObject(&csitx_config); vxReleaseImage(&(obj->csitx_image_exemplar)); vxReleaseGraph(&obj->csitx_graph); printf("[CsiTx_MODULE] - test done!\n"); //add for CsiTx reference end #endif obj->graph = vxCreateGraph(obj->context); status = vxGetStatus((vx_reference)obj->graph); if (status == VX_SUCCESS) { status = vxSetReferenceName((vx_reference)obj->graph, "app_multi_cam_graph"); APP_PRINTF("Graph create done!\n"); } if(status == VX_SUCCESS) { status = app_create_graph_capture(obj->graph, &obj->captureObj); APP_PRINTF("Capture graph done!\n"); } if( (1 == obj->enable_split_graph) && (status == VX_SUCCESS) ) { status = app_create_graph_obj_arr_split(obj->graph, &obj->objArrSplitObj); APP_PRINTF("Object array splitter graph done!\n"); } if(1 == obj->enable_viss) { if(status == VX_SUCCESS) { if(1 == obj->enable_split_graph) { status = app_create_graph_viss(obj->graph, &obj->vissObj, obj->objArrSplitObj.output0_arr, TIVX_TARGET_VPAC_VISS1); } else { status = app_create_graph_viss(obj->graph, &obj->vissObj, obj->captureObj.raw_image_arr[0], TIVX_TARGET_VPAC_VISS1); } APP_PRINTF("VISS graph done!\n"); } } if(1 == obj->enable_aewb) { if(status == VX_SUCCESS) { status = app_create_graph_aewb(obj->graph, &obj->aewbObj, obj->vissObj.h3a_stats_arr); APP_PRINTF("AEWB graph done!\n"); } } vx_int32 idx = 0; if(obj->sensorObj.enable_ldc == 1) { vx_object_array ldc_in_arr; if(1 == obj->enable_viss) { ldc_in_arr = obj->vissObj.output_arr; } else { ldc_in_arr = obj->objArrSplitObj.output0_arr; } if (status == VX_SUCCESS) { status = app_create_graph_ldc(obj->graph, &obj->ldcObj, ldc_in_arr, TIVX_TARGET_VPAC_LDC1); APP_PRINTF("LDC graph done!\n"); } obj->imgMosaicObj.input_arr[idx++] = obj->ldcObj.output_arr; APP_PRINTF("IDX = %i!\n",idx); } else { vx_object_array mosaic_in_arr; if(1 == obj->enable_viss) { mosaic_in_arr = obj->vissObj.output_arr; } else { mosaic_in_arr = obj->objArrSplitObj.output0_arr; } obj->imgMosaicObj.input_arr[idx++] = mosaic_in_arr; } if(1 == obj->enable_split_graph) { if(status == VX_SUCCESS) { #if defined(SOC_J784S4) status = app_create_graph_viss(obj->graph, &obj->vissObj1, obj->objArrSplitObj.output1_arr, TIVX_TARGET_VPAC2_VISS1); #else status = app_create_graph_viss(obj->graph, &obj->vissObj1, obj->objArrSplitObj.output1_arr, TIVX_TARGET_VPAC_VISS1); #endif vxSetReferenceName((vx_reference)obj->vissObj1.node, "viss_node2"); APP_PRINTF("VISS graph done!\n"); } if(1 == obj->enable_aewb) { if(status == VX_SUCCESS) { status = app_create_graph_aewb(obj->graph, &obj->aewbObj1, obj->vissObj1.h3a_stats_arr); vxSetReferenceName((vx_reference)obj->aewbObj1.node, "aewb_node2"); APP_PRINTF("AEWB graph done!\n"); } } if(obj->sensorObj.enable_ldc == 1) { vx_object_array ldc_in_arr; if(1 == obj->enable_split_graph) { ldc_in_arr = obj->vissObj1.output_arr; } else { ldc_in_arr = obj->objArrSplitObj.output1_arr; } if (status == VX_SUCCESS) { #if defined(SOC_J784S4) status = app_create_graph_ldc(obj->graph, &obj->ldcObj1, ldc_in_arr, TIVX_TARGET_VPAC2_LDC1); #else status = app_create_graph_ldc(obj->graph, &obj->ldcObj1, ldc_in_arr, TIVX_TARGET_VPAC_LDC1); #endif vxSetReferenceName((vx_reference)obj->ldcObj1.node, "ldc_node2"); APP_PRINTF("LDC graph done!\n"); } obj->imgMosaicObj.input_arr[idx++] = obj->ldcObj1.output_arr; APP_PRINTF("IDX = %i!\n",idx); } else { vx_object_array mosaic_in_arr; if(1 == obj->enable_split_graph) { mosaic_in_arr = obj->vissObj1.output_arr; } else { mosaic_in_arr = obj->objArrSplitObj.output1_arr; } obj->imgMosaicObj.input_arr[idx++] = mosaic_in_arr; } } vx_image display_in_image; if(obj->enable_mosaic == 1) { obj->imgMosaicObj.num_inputs = idx; if(status == VX_SUCCESS) { status = app_create_graph_img_mosaic(obj->graph, &obj->imgMosaicObj, NULL); APP_PRINTF("Img Mosaic graph done!\n"); } display_in_image = obj->imgMosaicObj.output_image[0]; } else { display_in_image = (vx_image)vxGetObjectArrayItem(obj->captureObj.raw_image_arr[0], 0); } if(status == VX_SUCCESS) { status = app_create_graph_display(obj->graph, &obj->displayObj, display_in_image); APP_PRINTF("Display graph done!\n"); } if(status == VX_SUCCESS) { graph_parameter_index = 0; add_graph_parameter_by_node_index(obj->graph, obj->captureObj.node, 1); obj->captureObj.graph_parameter_index = graph_parameter_index; graph_parameters_queue_params_list[graph_parameter_index].graph_parameter_index = graph_parameter_index; graph_parameters_queue_params_list[graph_parameter_index].refs_list_size = CAPTURE_BUFFER_Q_DEPTH; graph_parameters_queue_params_list[graph_parameter_index].refs_list = (vx_reference*)&obj->captureObj.raw_image_arr[0]; graph_parameter_index++; if((obj->en_out_img_write == 1) || (obj->test_mode == 1)) { add_graph_parameter_by_node_index(obj->graph, obj->imgMosaicObj.node, 1); obj->imgMosaicObj.graph_parameter_index = graph_parameter_index; graph_parameters_queue_params_list[graph_parameter_index].graph_parameter_index = graph_parameter_index; graph_parameters_queue_params_list[graph_parameter_index].refs_list_size = CAPTURE_BUFFER_Q_DEPTH; graph_parameters_queue_params_list[graph_parameter_index].refs_list = (vx_reference*)&obj->imgMosaicObj.output_image[0]; graph_parameter_index++; } status = vxSetGraphScheduleConfig(obj->graph, VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO, graph_parameter_index, graph_parameters_queue_params_list); if (status == VX_SUCCESS) { status = tivxSetGraphPipelineDepth(obj->graph, APP_PIPELINE_DEPTH); } if((obj->enable_viss == 1) && (status == VX_SUCCESS)) { status = tivxSetNodeParameterNumBufByIndex(obj->vissObj.node, 6, APP_BUFFER_Q_DEPTH); if (status == VX_SUCCESS) { status = tivxSetNodeParameterNumBufByIndex(obj->vissObj.node, 9, APP_BUFFER_Q_DEPTH); } } if((obj->enable_aewb == 1) && (status == VX_SUCCESS)) { if (status == VX_SUCCESS) { status = tivxSetNodeParameterNumBufByIndex(obj->aewbObj.node, 4, APP_BUFFER_Q_DEPTH); } } if((obj->sensorObj.enable_ldc == 1) && (status == VX_SUCCESS)) { status = tivxSetNodeParameterNumBufByIndex(obj->ldcObj.node, 7, APP_BUFFER_Q_DEPTH); } if((obj->enable_split_graph == 1) && (status == VX_SUCCESS)) { status = tivxSetNodeParameterNumBufByIndex(obj->vissObj1.node, 6, APP_BUFFER_Q_DEPTH); if (status == VX_SUCCESS) { status = tivxSetNodeParameterNumBufByIndex(obj->vissObj1.node, 9, APP_BUFFER_Q_DEPTH); } if((obj->enable_aewb == 1) && (status == VX_SUCCESS)) { if (status == VX_SUCCESS) { status = tivxSetNodeParameterNumBufByIndex(obj->aewbObj1.node, 4, APP_BUFFER_Q_DEPTH); } } if((obj->sensorObj.enable_ldc == 1) && (status == VX_SUCCESS)) { status = tivxSetNodeParameterNumBufByIndex(obj->ldcObj1.node, 7, APP_BUFFER_Q_DEPTH); } } if((obj->enable_mosaic == 1) && (status == VX_SUCCESS)) { if(!((obj->en_out_img_write == 1) || (obj->test_mode == 1))) { status = tivxSetNodeParameterNumBufByIndex(obj->imgMosaicObj.node, 1, CAPTURE_BUFFER_Q_DEPTH); APP_PRINTF("Pipeline params setup done!\n"); } } } return status; } static vx_status app_verify_graph(AppObj *obj) { vx_status status = VX_SUCCESS; status = vxVerifyGraph(obj->graph); if(status == VX_SUCCESS) { APP_PRINTF("Graph verify done!\n"); } #if 1 if(VX_SUCCESS == status) { status = tivxExportGraphToDot(obj->graph,".", "vx_app_multi_cam_ahp"); } #endif if (((obj->captureObj.enable_error_detection) || (obj->test_mode)) && (status == VX_SUCCESS)) { status = app_send_error_frame(&obj->captureObj); } #ifdef APP_TIVX_LOG_RT_ENABLE tivxLogRtTraceEnable(obj->graph); #endif /* wait a while for prints to flush */ tivxTaskWaitMsecs(100); return status; } static vx_status app_run_graph_for_one_frame_pipeline(AppObj *obj, vx_int32 frame_id) { vx_status status = VX_SUCCESS; APP_PRINTF("app_run_graph_for_one_pipeline: frame %d beginning\n", frame_id); appPerfPointBegin(&obj->total_perf); ImgMosaicObj *imgMosaicObj = &obj->imgMosaicObj; CaptureObj *captureObj = &obj->captureObj; /* checksum_actual is the checksum determined by the realtime test checksum_expected is the checksum that is expected to be the pipeline output */ uint32_t checksum_actual = 0; /* This is the number of frames required for the pipeline AWB and AE algorithms to stabilize (note that 15 is only required for the 6-8 camera use cases - others converge quicker) */ uint8_t stability_frame = 15; if(obj->pipeline < 0) { /* Enqueue outpus */ if ((obj->en_out_img_write == 1) || (obj->test_mode == 1)) { status = vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1); } /* Enqueue inputs during pipeup dont execute */ if (status == VX_SUCCESS) { status = vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&obj->captureObj.raw_image_arr[obj->enqueueCnt], 1); } obj->enqueueCnt++; obj->enqueueCnt = (obj->enqueueCnt >= CAPTURE_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt; obj->pipeline++; } if((obj->pipeline == 0) && (status == VX_SUCCESS)) { if((obj->en_out_img_write == 1) || (obj->test_mode == 1)) { status = vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1); } /* Execute 1st frame */ if(status == VX_SUCCESS) { status = vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&obj->captureObj.raw_image_arr[obj->enqueueCnt], 1); } obj->enqueueCnt++; obj->enqueueCnt = (obj->enqueueCnt >= CAPTURE_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt; obj->pipeline++; } if((obj->pipeline > 0) && (status == VX_SUCCESS)) { vx_object_array capture_input_arr; vx_image mosaic_output_image; uint32_t num_refs; /* Dequeue input */ status = vxGraphParameterDequeueDoneRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&capture_input_arr, 1, &num_refs); if((obj->en_out_img_write == 1) || (obj->test_mode == 1)) { vx_char output_file_name[APP_MAX_FILE_PATH]; /* Dequeue output */ if (status == VX_SUCCESS) { status = vxGraphParameterDequeueDoneRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1, &num_refs); } if ((status == VX_SUCCESS) && (obj->test_mode == 1) && (frame_id > TEST_BUFFER)) { /* calculate the checksum of the mosaic output */ if ((app_test_check_image(mosaic_output_image, checksums_expected[obj->sensorObj.sensor_index][obj->sensorObj.num_cameras_enabled-1], &checksum_actual) != vx_true_e) && (frame_id > stability_frame)) { test_result = vx_false_e; /* in case test fails and needs to change */ populate_gatherer(obj->sensorObj.sensor_index, obj->sensorObj.num_cameras_enabled-1, checksum_actual); } } if (obj->en_out_img_write == 1) { appPerfPointBegin(&obj->fileio_perf); snprintf(output_file_name, APP_MAX_FILE_PATH, "%s/mosaic_output_%010d_%dx%d.yuv", obj->output_file_path, (frame_id - CAPTURE_BUFFER_Q_DEPTH), imgMosaicObj->out_width, imgMosaicObj->out_height); if (status == VX_SUCCESS) { status = writeMosaicOutput(output_file_name, mosaic_output_image); } appPerfPointEnd(&obj->fileio_perf); } /* Enqueue output */ if (status == VX_SUCCESS) { status = vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1); } } /* Enqueue input - start execution */ if (status == VX_SUCCESS) { status = vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&capture_input_arr, 1); } obj->enqueueCnt++; obj->dequeueCnt++; obj->enqueueCnt = (obj->enqueueCnt >= CAPTURE_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt; obj->dequeueCnt = (obj->dequeueCnt >= CAPTURE_BUFFER_Q_DEPTH)? 0 : obj->dequeueCnt; } appPerfPointEnd(&obj->total_perf); return status; } static vx_status app_run_graph(AppObj *obj) { vx_status status = VX_SUCCESS; SensorObj *sensorObj = &obj->sensorObj; vx_int32 frame_id; int32_t ch_mask = obj->sensorObj.ch_mask; app_pipeline_params_defaults(obj); APP_PRINTF("app_pipeline_params_defaults returned\n"); if(NULL == sensorObj->sensor_name) { printf("sensor name is NULL \n"); return VX_FAILURE; } // if test_mode is enabled, don't fail the program if the sensor init fails if( (obj->test_mode) || (obj->captureObj.enable_error_detection) ) { appStartImageSensor(sensorObj->sensor_name, ch_mask); } else { status = appStartImageSensor(sensorObj->sensor_name, ch_mask); APP_PRINTF("appStartImageSensor returned with status: %d\n", status); } if(0 == obj->enable_viss) { obj->vissObj.en_out_viss_write = 0; } if(0 == obj->enable_split_graph) { obj->vissObj1.en_out_viss_write = 0; } if (obj->test_mode == 1) { // The buffer allows AWB/AE algos to converge before checksums are calculated obj->num_frames_to_run = TEST_BUFFER + 30; } for(frame_id = 0; frame_id < obj->num_frames_to_run; frame_id++) { if(obj->write_file == 1) { if((obj->captureObj.en_out_capture_write == 1) && (status == VX_SUCCESS)) { status = app_send_cmd_capture_write_node(&obj->captureObj, frame_id, obj->num_frames_to_write, obj->num_frames_to_skip); } if((obj->vissObj.en_out_viss_write == 1) && (status == VX_SUCCESS)) { status = app_send_cmd_viss_write_node(&obj->vissObj, frame_id, obj->num_frames_to_write, obj->num_frames_to_skip); } if((obj->vissObj1.en_out_viss_write == 1) && (status == VX_SUCCESS)) { status = app_send_cmd_viss_write_node(&obj->vissObj1, frame_id, obj->num_frames_to_write, obj->num_frames_to_skip); } if((obj->ldcObj.en_out_ldc_write == 1) && (status == VX_SUCCESS)) { status = app_send_cmd_ldc_write_node(&obj->ldcObj, frame_id, obj->num_frames_to_write, obj->num_frames_to_skip); } if((obj->ldcObj1.en_out_ldc_write == 1) && (status == VX_SUCCESS)) { status = app_send_cmd_ldc_write_node(&obj->ldcObj1, frame_id, obj->num_frames_to_write, obj->num_frames_to_skip); } obj->write_file = 0; } if (status == VX_SUCCESS) { status = app_run_graph_for_one_frame_pipeline(obj, frame_id); } /* user asked to stop processing */ if(obj->stop_task) break; } if (status == VX_SUCCESS) { status = vxWaitGraph(obj->graph); } obj->stop_task = 1; if (status == VX_SUCCESS) { status = appStopImageSensor(obj->sensorObj.sensor_name, ch_mask); } return status; } static void set_display_defaults(DisplayObj *displayObj) { displayObj->display_option = 1; } static void app_pipeline_params_defaults(AppObj *obj) { obj->pipeline = -CAPTURE_BUFFER_Q_DEPTH + 1; obj->enqueueCnt = 0; obj->dequeueCnt = 0; } static void set_sensor_defaults(SensorObj *sensorObj) { strcpy(sensorObj->sensor_name, SENSOR_SONY_IMX390_UB953_D3); sensorObj->num_sensors_found = 0; sensorObj->sensor_features_enabled = 0; sensorObj->sensor_features_supported = 0; sensorObj->sensor_dcc_enabled = 0; sensorObj->sensor_wdr_enabled = 0; sensorObj->sensor_exp_control_enabled = 0; sensorObj->sensor_gain_control_enabled = 0; } static void app_default_param_set(AppObj *obj) { set_sensor_defaults(&obj->sensorObj); set_display_defaults(&obj->displayObj); app_pipeline_params_defaults(obj); obj->is_interactive = 1; obj->test_mode = 0; obj->write_file = 0; obj->bypass_split_graph = 0; obj->sensorObj.enable_ldc = 0; obj->sensorObj.num_cameras_enabled = 1; obj->sensorObj.ch_mask = 0x1; obj->sensorObj.usecase_option = APP_SENSOR_FEATURE_CFG_UC0; } static vx_int32 calc_grid_size(vx_uint32 ch) { if(0==ch) { return -1; } else if(1==ch) { return 1; } else if(4>=ch) { return 2; } else if(9>=ch) { return 3; } else if(16>=ch) { return 4; }else { return -1; } } static void set_img_mosaic_params(ImgMosaicObj *imgMosaicObj, vx_uint32 in_width, vx_uint32 in_height, vx_int32 numCh, ObjArrSplitObj *objArrSplitObj, int32_t enable_split_graph) { vx_int32 idx, ch; vx_int32 grid_size = calc_grid_size(numCh); imgMosaicObj->out_width = DISPLAY_WIDTH; imgMosaicObj->out_height = DISPLAY_HEIGHT; if (1 == enable_split_graph) { imgMosaicObj->num_inputs = 2; } else { imgMosaicObj->num_inputs = 1; } idx = 0; tivxImgMosaicParamsSetDefaults(&imgMosaicObj->params); for(ch = 0; ch < numCh; ch++) { vx_int32 winX = ch%grid_size; vx_int32 winY = ch/grid_size; imgMosaicObj->params.windows[idx].startX = (winX * (in_width/grid_size)); imgMosaicObj->params.windows[idx].startY = (winY * (in_height/grid_size)); imgMosaicObj->params.windows[idx].width = in_width/grid_size; imgMosaicObj->params.windows[idx].height = in_height/grid_size; imgMosaicObj->params.windows[idx].input_select = 0; if (1 == enable_split_graph) { if(ch >= objArrSplitObj->output0_num_elements) { imgMosaicObj->params.windows[idx].input_select = 1; } imgMosaicObj->params.windows[idx].channel_select = ch%objArrSplitObj->output0_num_elements; } else { imgMosaicObj->params.windows[idx].channel_select = ch; } idx++; } imgMosaicObj->params.num_windows = idx; /* Number of time to clear the output buffer before it gets reused */ imgMosaicObj->params.clear_count = CAPTURE_BUFFER_Q_DEPTH; } static void app_update_param_set(AppObj *obj) { vx_uint16 resized_width, resized_height; appIssGetResizeParams(obj->sensorObj.image_width, obj->sensorObj.image_height, DISPLAY_WIDTH, DISPLAY_HEIGHT, &resized_width, &resized_height); if ( (obj->sensorObj.num_cameras_enabled == 1)) { obj->objArrSplitObj.output0_num_elements = 1; obj->objArrSplitObj.output1_num_elements = 0; obj->enable_split_graph = 0; } else if (1 == obj->bypass_split_graph) { obj->objArrSplitObj.output0_num_elements = obj->sensorObj.num_cameras_enabled; obj->objArrSplitObj.output1_num_elements = 0; obj->enable_split_graph = 0; } else { obj->objArrSplitObj.output0_num_elements = (obj->sensorObj.num_cameras_enabled + 1) / 2; obj->objArrSplitObj.output1_num_elements = obj->sensorObj.num_cameras_enabled - obj->objArrSplitObj.output0_num_elements; } set_img_mosaic_params(&obj->imgMosaicObj, resized_width, resized_height, obj->sensorObj.num_cameras_enabled, &obj->objArrSplitObj, obj->enable_split_graph); } /* * Utility API used to add a graph parameter from a node, node parameter index */ static 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(¶meter); } static void app_draw_graphics(Draw2D_Handle *handle, Draw2D_BufInfo *draw2dBufInfo, uint32_t update_type) { appGrpxDrawDefault(handle, draw2dBufInfo, update_type); if(update_type == 0) { Draw2D_FontPrm sHeading; sHeading.fontIdx = 4; Draw2D_drawString(handle, 700, 5, "Multi Cam Demo", &sHeading); } return; }
Flash SDcard
compile rtos sdk by 'make sdk ' and the `make linux_fs_install_sd ` to apply modification
Error occured. I mentioned above that I fixed this issue by removing the addr_translate in example.syscfg which seems not correct way.
How to fix this ?
Thank you in advance.
BR
stream
Hi stream,
ok, let me check it on the EVM. I will check some later this week.
Regards,
Brijesh
Hi Stream,
I see no reason why the code in SDK9.2 will not work.
It essentially calls two APIs
1, tivxMemShared2PhysPtr: This is used to convert shared address to physical address. It calls tivxMemShared2PhysPtr -> appMemShared2PhysPtr -> target2SharedFxn -> appTarget2SharedConversion, which essentially returns the same physical address as given shared address.
2, tivxMemShared2TargetPtr: This is used to convert shared address to local mapped address. It calls tivxMemShared2TargetPtr -> appMemShared2TargetPtr -> shared2TargetFxn -> appShared2TargetConversion, which essentially maps physical address to local mapped address.
So it should work fine. What exactly issue are you facing? Are you seeing incorrect output buffer or are you seeing some incorrect programming in the CSITX?
Regards,
Brijesh
Hi Brijesh :
What exactly issue are you facing?
Sorry, let me make it clear :
All my confusion is :
I add my code to enable csitx to new SDK9.2 , vision_apps/apps/basic_demos/app_multi_cam/main.c , and copy the compiled app to SDcard.
using TDA4VEN EVM , SDcard boot mode,
After run `vx_app_arm_multi_cam.out` under /opt/vision_apps/ , log showed that:
tivxMemShared2PhysPtr: This is used to convert shared address to physical address
I also think the function itself should be work fine , temporarily forget the discussion about this function. Let's get the the error above I confronted in the beginning passed .
By the way , Have you tested the new SDK9.2 with the code I provided ? All works fine ?
BR
stream
Hi Stream,
I still have not got the chance to try it out on EVM.
Regards,
Brijesh
Hi,
Sorry for the delay.
We are able to re-produce the issue.
Please use below changes in "SDK/video_io/kernels/video_io/host/vx_scitx_host.c" under "tivx_csitx_params_init" API, and build the sdk using sdkbuilder and run CSITx demo.
Best Regards,
Sudheer
Hi TI experts:
I add your modification into my code ,and have validated the video data loop : SoC csitx --> serializer --> deserializer --> device that received csi mipi data
Finally, we have got the correct ouput from the end , it means that the modification works .
Thank you for your efforts!!
BR
stream