OV7740 camera on I.MX6 using CSI0 in BT.656 mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OV7740 camera on I.MX6 using CSI0 in BT.656 mode

10,677 Views
robert_lim
Contributor II

I am using an imx.6 Sabrelite (PN:BD-S1-imx6) from BoundaryDevices to develop a camera system. The camera sensor is the ov7740 from omnivision, attached to Sabrelite via CSI0 (8 data lines, pixelclock and camera system clock). As I do not have the possibility to connect the hsync and vsync signal this all has to work in BT.656 mode.

I am having issue getting images from the driver. The video for linux drivers hangs waiting for data and after a timeout breaks down the video4 linux pipeline.

The steps I have taken so far:

  1. Started with working kernel (boundary-imx_3.10.17_1.0.0_beta) and
  2. Made sure that the camera is detected and can be configured over I2C.
  3. Built a driver, OV7740.c, based on OV5642.c with the following changes:
    1. Replaced modes  to generate a 640x480 30 fps data on the OV7740     
    2. Changed the chip_id     
    3. Changed ov7740_data.pix.pixelformat to V4L2_PIX_FMT_YVU420     
    4. Added V4L2 required IOCTL functions

  1. Sensor is correctly detected on I2C
  2. PCLK and XCLK are correct
  3. Use tool: mxc_v4l2_capture.out and gstreamer to try to capture sensor data

The test encounter DQBUF failed during capturing, the error is as follow:

ERROR: v4l2 capture: mxc_v4l_dqueue timeout enc_counter 0 VIDIOC_DQBUF failed.

When trying to decipher the video for linux kernel module, it seems that this occurs when the data queue hasn't been filled until a certain timeout. The queue should be filled through the CSI interrupt handler. As I can see it now, it seems that the interrupt is never raised.

I have taken the following link which have similar problem using BT656 mode to capture in progressive mode as a reference:

https://community.freescale.com/thread/309869

https://community.freescale.com/docs/DOC-95412

For more info, below summarize our setting and dumped info to get the CSI BT656 without HSYNC/VSYNC working:

  1. function ioctl_g_ifparm() sets p->u.bt656.bt_sync_correct = 0:
  2. modify the code in mxc_v4l2_s_param(), let csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE
  3. The CSI0 connects parallel, IOMUXC_GPR1 = 0x48693005 and IPU_CONF = 0x00000785

14010_14010.jpg1.JPG.jpg

14013_14013.jpg2.jpg

I think this is due to the CSI/IPU not setup properly for BT.656 mode without hsync/vsync signals. Please give some support on how to configure the CSI/IPU with this camera?

Thanks in advance.

30 Replies

594 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

Hi Robert, from these waveform, I think it can be supported. How about the CSI_DATA_EN pin? The CSI will capture data only when this pin is active.

By th way, can you help to dump the IPU CSI related registers:

IPUx_CSI0_SENS_CONF

IPUx_CSI0_SENS_FRM_SIZE

IPUx_CSI0_ACT_FRM_SIZE

IPUx_CSI0_OUT_FRM_CTRL

IPUx_CSI0_CCIR_CODE_1

IPUx_CSI0_CCIR_CODE_2

IPUx_CSI0_CCIR_CODE_3

And also dump the IPU IDMAC 0 setting, it can be dumpped from file ipu_param_mem.h, function _ipu_ch_param_dump().

0 Kudos

594 Views
robert_lim
Contributor II

Hi Qiang Li,

Bellows are IPU_CSI and IDMAC related registers and values:

CSI_SENS_CONF = 0x000A0908

CSI_SENS_FRM_SIZE = 0x01DF027F

CSI_ACT_FRM_SIZE = 0x01DF027F

CSI_OUT_FRM_CTRL = 0x00000000

CSI_TST_CTRL = 0x00000000

CSI_CCIR_CODE_1 = 0x00000000

CSI_CCIR_CODE_2 = 0x00000000

CSI_CCIR_CODE_3 = 0x00000000

CSI_MIPI_DI = 0xFFFFFFFF

CSI_SKIP = 0x00000000

CSI_CPD_CTRL = 0x00000000

CSI_CPD_RC = 0x00000000

CSI_CPD_RS = 0x00000000

CSI_CPD_GRC = 0x00000000

CSI_CPD_GRS = 0x00000000

CSI_CPD_GBC = 0x00000000

CSI_CPD_GBS = 0x00000000

CSI_CPD_BC = 0x00000000

CSI_CPD_BS = 0x00000000

CSI_CPD_OFFSET1 = 0x00000000

CSI_CPD_OFFSET2 = 0x00000000

IPU_CONF = 0x00000680

IDMAC_CONF = 0x0000002F

IDMAC_CHA_EN1 = 0x10000000

IDMAC_CHA_EN2 = 0x00000000

IDMAC_CHA_PRI1 = 0x18800001

IDMAC_CHA_PRI2 = 0x00000000

IDMAC_BAND_EN1 = 0x00000000

IDMAC_BAND_EN2 = 0x00000000

IPU_CHA_DB_MODE_SEL0 = 0x00000000

IPU_CHA_DB_MODE_SEL1 = 0x00000000

IPU_CHA_TRB_MODE_SEL0 = 0x10000000

IPU_CHA_TRB_MODE_SEL1 = 0x00000000

DMFC_WR_CHAN = 0x00000090

DMFC_WR_CHAN_DEF = 0x202020F6

DMFC_DP_CHAN = 0x0000968A

DMFC_DP_CHAN_DEF = 0x2020F6F6

DMFC_IC_CTRL = 0x00000002

IPU_FS_PROC_FLOW1 = 0x00000000

IPU_FS_PROC_FLOW2 = 0x00000000

IPU_FS_PROC_FLOW3 = 0x00000000

IPU_FS_DISP_FLOW1 = 0x00000000

IPU_VDIC_VDI_FSIZE = 0x00000000

IPU_VDIC_VDI_C = 0x00000000

IPU_IC_CONF = 0x00000000

Many thanks for your help!

Regards,

Robert

0 Kudos

594 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

Hi Robert, from your setting,I had found the followed issues:

In CSI_SENS_CONF, CSI0_DATA_DEST should be 0x2, destination is IDMAC via SMFC.

In CSI_SENS_FRM_SIZE, it should include blank data of VSYNC and HSYNC, so it is not same as CSI_ACT_FRM_SIZE.

In CSI_CCIR_CODE_X registes, they should not be 0, please check ipu_capture.c, function ipu_csi_init_interface():

/* Set CCIR registers */

if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {

  ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);

  ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);


0 Kudos

594 Views
robert_lim
Contributor II

Hi Qiang Li,

Re-dump the registers as below :

CSI_SENS_CONF = 0x04000928

CSI_SENS_FRM_SIZE = 0x01DF027F

CSI_ACT_FRM_SIZE = 0x01DF027F

CSI_OUT_FRM_CTRL = 0x00000000

CSI_TST_CTRL = 0x00000000

CSI_CCIR_CODE_1 = 0x00040030

CSI_CCIR_CODE_2 = 0x00000000

CSI_CCIR_CODE_3 = 0x00FF0000

CSI_MIPI_DI = 0xFFFFFFFF

CSI_SKIP = 0x00000000

CSI_CPD_CTRL = 0x00000000

CSI_CPD_RC = 0x00000000

CSI_CPD_RS = 0x00000000

CSI_CPD_GRC = 0x00000000

CSI_CPD_GRS = 0x00000000

CSI_CPD_GBC = 0x00000000

CSI_CPD_GBS = 0x00000000

CSI_CPD_BC = 0x00000000

CSI_CPD_BS = 0x00000000

CSI_CPD_OFFSET1 = 0x00000000

CSI_CPD_OFFSET2 = 0x00000000

IPU_CONF = 0x00000781

IDMAC_CONF = 0x0000002F

IDMAC_CHA_EN1 = 0x10000001

IDMAC_CHA_EN2 = 0x00000000

IDMAC_CHA_PRI1 = 0x18800001

IDMAC_CHA_PRI2 = 0x00000000

IDMAC_BAND_EN1 = 0x00000000

IDMAC_BAND_EN2 = 0x00000000

IPU_CHA_DB_MODE_SEL0 = 0x00000001

IPU_CHA_DB_MODE_SEL1 = 0x00000000

IPU_CHA_TRB_MODE_SEL0 = 0x10000000

IPU_CHA_TRB_MODE_SEL1 = 0x00000000

DMFC_WR_CHAN = 0x00000090

DMFC_WR_CHAN_DEF = 0x202020F6

DMFC_DP_CHAN = 0x0000968A

DMFC_DP_CHAN_DEF = 0x2020F6F6

DMFC_IC_CTRL = 0x00000002

IPU_FS_PROC_FLOW1 = 0x00000000

IPU_FS_PROC_FLOW2 = 0x00000000

IPU_FS_PROC_FLOW3 = 0x00000000

IPU_FS_DISP_FLOW1 = 0x00000000

IPU_VDIC_VDI_FSIZE = 0x00000000

IPU_VDIC_VDI_C = 0x00000000

IPU_IC_CONF = 0x00000000

CSI_SENS_CONF, CSI0_DATA_DEST is 0x2 (destination is IDMAC via SMFC) now.

CSI_CCIR_CODE_X are not 0 now.

But CSI_SENS_FRM_SIZE is still same with CSI_ACT_FRM_SIZE.

Need your advices on how to correct this part, thanks in advanced!

I am using BT656 mode without external VSYNC and HSYNC, should CSI_SENS_FRM_SIZE still be included blank data of VSYNC and HSYNC?

Thanks and Regards,

Robert

0 Kudos

593 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

Hi Robert, yes, CSI_SENS_FRM_SIZE should include blank data.

In mxc_v4l2_capture.c, the default code can only support 2 BT656 format, NTSC and PAL, you should add the other formats for OV7740. The raw_width and raw_height are the setting in CSI_SENS_FRM_SIZE, the active_width and the active_height are the setting in CSI_SENS_ACT_SIZE. And in this setting, in your ov7740 probe function, you should set ov7740_data.sen.pix.priv = 1;

      ov7740_data.sen.pix.priv = 1;  /* 1 is used to indicate TV in */

static video_fmt_t video_fmts[] = {

{   /*! NTSC */

  .v4l2_id = V4L2_STD_NTSC,

  .name = "NTSC",

  .raw_width = 720,  /* SENS_FRM_WIDTH */

  .raw_height = 525,  /* SENS_FRM_HEIGHT */

  .active_width = 720,  /* ACT_FRM_WIDTH */

  .active_height = 480,  /* ACT_FRM_HEIGHT */

  .active_top = 13,

  .active_left = 0,

  },

{   /*! (B, G, H, I, N) PAL */

  .v4l2_id = V4L2_STD_PAL,

  .name = "PAL",

  .raw_width = 720,

  .raw_height = 625,

  .active_width = 720,

  .active_height = 576,

  .active_top = 0,

  .active_left = 0,

  },

0 Kudos

594 Views
robert_lim
Contributor II

Hi Qiang Li,

For further confirmation, meaning I should add/modify the following codes in ov7740.c?

static video_fmt_idx video_idx = OV7740_PAL;  <-- Pick PAL as example.

typedef enum {

  OV7740_NTSC = 0, /*!< Locked on (M) NTSC video signal. */

  OV7740_PAL, /*!< (B, G, H, I, N)PAL video signal. */

} video_fmt_idx;

static video_fmt_t video_fmts[] = {

{   /*! NTSC */

  .v4l2_id = V4L2_STD_NTSC,

  .name = "NTSC",

  .raw_width = 720,  /* SENS_FRM_WIDTH */

  .raw_height = 525,  /* SENS_FRM_HEIGHT */

  .active_width = 720,  /* ACT_FRM_WIDTH */

  .active_height = 480,  /* ACT_FRM_HEIGHT */

  .active_top = 13,

  .active_left = 0,

  },

{   /*! (B, G, H, I, N) PAL */

  .v4l2_id = V4L2_STD_PAL,

  .name = "PAL",

  .raw_width = 720,

  .raw_height = 625,

  .active_width = 720,

  .active_height = 576,

  .active_top = 0,

  .active_left = 0,

  },

In probe function:

ov7740_data.sen.pix.width = video_fmts[video_idx].raw_width;
ov7740_data.sen.pix.height = video_fmts[video_idx].raw_height;
ov7740_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY;  /* YUV422 */
ov7740_data.sen.pix.priv = 1;  /* 1 is used to indicate TV in */
ov7740_data.sen.on = true;

The following are original codes from my implementation:

ov7740_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
ov7740_data.pix.width = 640;
ov7740_data.pix.height = 480;

I was fixed the width = 640 and height = 480 as in ov5642.c, and no data.sen.pix.priv was set.

Thanks for your help!

Regards,

Robert

0 Kudos

594 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

For the BT656 input with EAV/SAV, you should reference to the TVin driver, such as the adv7180.

0 Kudos

594 Views
robert_lim
Contributor II

Hi Qiang Li,

ov7740 is a digital camera, it support only VGA, QVGA, CIF and any size smaller. Adv7180 is a analog divice which support NTSC and PAL mode. Your suggestion is to add NTSC and PAL supports for ov7740, because in mxc_v4l2_capture.c, the default code can only support 2 BT656 format-- NTSC and PAL.

To make it works, Is it possible to force the digital camera to support analog format? Or is it an easier way to change mxc_v4l2_capture.c to support VGA for BT656 format than transform digital to analog format? From mxc_v4l2_capture.c I found that only mxc_v4l2_s_std() function implements for these modes. Not sure if the video for linux layer support only PAL and NTSC for BT656?

Thanks in advanced for your advice.

Regards,

Robert

0 Kudos

594 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

My suggestion is to add new formats for your camera sensor, just reference to the current PAL and NTSC.

In fact, I think the key point is that you should set CSI_SENS_FRM_SIZE with blank size, if you use the default camera sensor driver code, the CSI_SENS_FRM_SIZE will be set to same as CSI_SENS_ACT_SIZE.

For test, I think you can also hardcoding the CSI_SENS_FRM_SIZE.

0 Kudos

594 Views
YixingKong
Senior Contributor IV

LI Qiang, the customer still could not get the camera working. Do you have any more suggestion?

Thanks,

Yixing

0 Kudos