1: Now i use tp2825 on imx6q with android. The kenel version is 3.0.35.
2: 720p cvbs camera is ok on the same board with tp2825
3: For the tp2825, the input single is cvbs camera with NTSC ,which is interlaced and resolution is 720*480,The output is BT656 with 8 bits.
4: In decode ic tp2825 driver, i get the BT656 data and output it to LCD.,but the image id scrolling. Is it wrong with tp2825 register in driver or drawing data to LCD in mxc_v4l2_tvin.c ?
thanks!
in driver file tp2825.c
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 plus 1 */
.active_height = 480, /* ACT_FRM_WIDTH plus 1 */
.frame_rate = 30, /* 30 */
},
{ /*! (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,
.frame_rate = 25,
},
{ /*! Unlocked standard */
.v4l2_id = V4L2_STD_ALL,
.name = "Autodetect",
.raw_width = 720,
.raw_height = 625,
.active_width = 720,
.active_height = 576,
.frame_rate = 25,
},
};
static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
{
dev_dbg(&tp2825_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
if (s == NULL) {
pr_err(" ERROR!! no slave device set!\n");
return -1;
}
memset(p, 0, sizeof(*p));
p->if_type = V4L2_IF_TYPE_BT656;
p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
#if 1
p->u.bt656.nobt_hs_inv = 0;
p->u.bt656.bt_sync_correct = 0;
p->u.bt656.clock_curr = 0; /* interlace clock mode orig = 0 */
p->u.bt656.latch_clk_inv =1;
#else
p->u.bt656.nobt_hs_inv = 1;
p->u.bt656.bt_sync_correct = 1;
#endif
return 0;
}
static int tp2825_probe(struct i2c_client *client,const struct i2c_device_id *id)
{ .................................................................................................
video_idx = TP2825_NTSC;
tp2825_data.sen.pix.width = video_fmts[video_idx].raw_width;
tp2825_data.sen.pix.height = video_fmts[video_idx].raw_height;
tp2825_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
tp2825_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
tp2825_data.sen.on = true;
tp2825_data.sen.mclk = 74250000;
tp2825_data.sen.sensor_clk = clk_get(NULL, "csi_mclk");
tp2825_data.sen.mclk_source = 0;
tp2825_data.sen.csi = 0;
..............................................................................................
}
in camera driver:
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,//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,
},
{ /*! Unlocked standard */
.v4l2_id = V4L2_STD_ALL,
.name = "Autodetect",
.raw_width = 720,
.raw_height = 625,
.active_width = 720,
.active_height = 576,
.active_top = 0,
.active_left = 0,
},
};
static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
{ ............................
if (ifparm.u.bt656.clock_curr == 0)
csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED ;
.................................
}
static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
{ ............................
cam->crop_bounds.left = 0;
cam->crop_bounds.width = 720;
cam->crop_bounds.top = 0;
cam->crop_bounds.height = 480;
cam->crop_current = cam->crop_defrect = cam->crop_bounds;
ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
cam->crop_current.height, cam->csi);
ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
cam->crop_current.top, cam->csi);
cam->streamparm.parm.capture.capturemode = 0;
cam->standard.index = 0;
cam->standard.id = V4L2_STD_UNKNOWN;
cam->standard.frameperiod.denominator = 30;
cam->standard.frameperiod.numerator = 1;
cam->standard.framelines = 480;
cam->standard_autodetect = true;
cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
cam->overlay_on = false;
cam->capture_on = false;
cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
cam->v2f.fmt.pix.sizeimage = 720 * 480 * 2;
cam->v2f.fmt.pix.bytesperline =720*2;
cam->v2f.fmt.pix.width = 720;
cam->v2f.fmt.pix.height = 480;
cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
cam->win.w.width = 720;
cam->win.w.height = 720;
cam->win.w.left = 0;
cam->win.w.top = 0;
.................................
}
my test file is mxc_v4l2_tvin.c,which is at externel/external/linux-test/test/mxc_v4l2_test/.
command:
./mxc-v4l2-tvin -ow 1080 -oh 720 -ol 420 -ot 0 -tb -f UYVY
in the mxc_v4l2_tvin.c
unsigned char arr[691200]; //add
int mxc_v4l_tvin_test(void)
{........................................
int h, e, o;
if (i%2 == 0)
{
for (h = 0, e = 0; h < 480; h += 2, e++)
{
memcpy(&arr[h*1440], capture_buffers[capture_buf.index].start+e*1440, 1440);
}
}
else
{
for (h = 1, o = 0; h < 480; h += 2, o++)
{
memcpy(&arr[h*1440], capture_buffers[capture_buf.index].start+o*1440,1440);
}
}
printf("g_frame_size=%d\n",g_frame_size);
memcpy(output_buffers[output_buf.index].start, arr, g_frame_size);
.........................................
}
Hello Xiaojun,
如果出现滚屏的现象,一般是2个原因造成的:
(1)camera端和CPU CSI端,数据格式没有对应好。
比如camera数据是PAL,CSI端是NTSC;或者反过来。都会滚屏。所以,你在mxc_v4l2_capture.c中跟踪一下进来的格式。
(2)CSI端接收的image分辨率要是偶数行。
比如,曾经遇到过一位客户CSI接收到的分辨率是720x507的,就滚屏了。
另外,在我们的BSP中,AV7180已经非常成熟了,你完全可以参考它的driver来配置你的decoder.
Have a nice day!
TIC Weidong