基于i.mx6高清视频采集技术详解

news/2024/12/2 18:34:37/

1    概述

本文介绍基于freescale i.MX6 高清视频采集方案的技术详解,高清视频输入可以为HDMIDVI或者VGA的方式。分辨率支持1600*1200@60、1920*1080@60、1280x720@60HZ等多种。视频解码芯片采用ADI的ADV7441A。

实现低成本、高性能、高集成度的视频采集产品。

包括硬件设计详解、软件设计详解。

注:板卡采用成都嵌智捷科技的I.MX6工业核心板。

录制的1080p视频:

2    功能列表

序号

功能

详细说明

1

处理器

Freescale’s i.MX6 Dual CPUs: ARM Cortex A9, each @ 1GHz

2

内存

1GB DDR3 1066MHz

3

存储器

Emmc NAND FLASH 4GB

4

TF卡

TF卡,

5

以太网

10M/100/100M以太网

6

USB HOST

USB HOST,USB 2.0

7

固态硬盘

Msata硬盘

8

高清视频输入

支持一路VGA或者HDMI或者DVI高清视频输入,分辨率为1600*1200@60或者1920*1080@60或者1280x720@60HZ等

9

H.264或者MPEG4编码

支持H.264或者MPEG4编码,分辨率至少为1600*1200@30或者1920*1080@30或者1280x720@60HZ等

10

操作系统

Linux 3.0.15

11

工作温度

-40℃-70℃

3    系统框图

产品系统主要包括i.MX6 Dual处理器、以太网、高清视频解码芯片、固体硬盘、USB HOST以及调试串口。

功能见如下框图

更多详细技术信息请参看成都嵌智捷科技网站或咨询公司技术支持,http://www.nidetech.com

4    软件设计

4.1       CSI框图

 

 

4.2   ADV7441A I2C寄存器设置

42 03 0C ; Disable TOD

42 05 02 ; Prim_Mode =010b for automatic graphics mode

42 06 07 ; VID_STD=00111b for automatic graphics mode

42 1D 40 ; Disable TRI_LLC

42 3C A8 ; SOG Sync level for atenuated sync, PLL Qpump to default

42 37 00 ; PCLK Polarity

42 47 0A ; Enable Automatic PLL_Qpump and VCO Range

42 68 F2 ; Auto CSC, RGB Out

42 6B F2 ; Setup CPOP_SEL & DE Enable

42 7B 1D ; Turn off EAV and SAV codes

42 7C 00 ; HS/VS Positive

42 7E 03 ; HS Adjust

42 7F 88 ; VS Adjust

42 F4 3F ; Max Drive Strength

42 87 E8 ; Enable Manual PLL Divider Ratio 0x870 = 2160

42 88 70 ; Set PLL Divider Ratio

42 8C 07 ; HS adjust

42 8D 5A ; HS adjust

42 8E 87 ; VBI Adjust

42 8F 01 ; Set Free Run Line Length 0x17E = 382

42 90 7E ; Set Free Run Line Length

42 AB 4E ; Set Line Count Max 0x4E2 = 1250

42 AC 20 ; Set Line Count Max

42 B5 08 ; Deglitch Filter adjust

42 91 10 ; Progressive

4.3   引脚定义

static iomux_v3_cfg_t mx6q_sabresd_csi1_sensor_pads[] = {

        /* IPU2 tvin */

        MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9,

        MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8,

        MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7,

        MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6,

        MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5,

        MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4,

        MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3,

        MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2,

        MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19,

        MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18,

        MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17,

        MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16,

        MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15,

        MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14,

        MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13,

        MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12,

        MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK,

        MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC,

        MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC,

        MX6Q_PAD_EIM_D31__GPIO_3_31,            /* tvin reset , low */

};

4.4   adv7441a复位和CPU相应寄存器初始化

       #define SABRESD_TVIN_REST       IMX_GPIO_NR(3, 31)

       static void mx6q_csi1_io_init(void)

{

        mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_csi1_sensor_pads,

                ARRAY_SIZE(mx6q_sabresd_csi1_sensor_pads));

        /* tvin reset */

        gpio_request(SABRESD_TVIN_REST, "tvin-rest");

        gpio_direction_output(SABRESD_TVIN_REST, 1);

        gpio_direction_output(SABRESD_TVIN_REST, 0);

        msleep(10);

        gpio_direction_output(SABRESD_TVIN_REST, 1);

        /* For MX6Q:

         * GPR1 bit19 and bit20 meaning:

         * Bit19:       0 - Enable mipi to IPU1 CSI0

         *                      virtual channel is fixed to 0

         *              1 - Enable parallel interface to IPU1 CSI0

         * Bit20:       0 - Enable mipi to IPU2 CSI1

         *                      virtual channel is fixed to 3

         *              1 - Enable parallel interface to IPU2 CSI1

         * IPU1 CSI1 directly connect to mipi csi2,

         *      virtual channel is fixed to 1

         * IPU2 CSI0 directly connect to mipi csi2,

         *      virtual channel is fixed to 2

         * For MX6DL:

         * GPR13 bit 0-2 IPU_CSI0_MUX

         *   000 MIPI_CSI0

         *   100 IPU CSI0

        if (cpu_is_mx6q())

                mxc_iomux_set_gpr_register(1, 20, 1, 1);

 //  CPU工作在IPU2 CSI1

        else if (cpu_is_mx6dl())

                mxc_iomux_set_gpr_register(13, 0, 3, 4);

}

 

 

 

4.5   V4L主设备驱动

 

static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)

        if (ifparm.if_type == V4L2_IF_TYPE_BT656) {

            if (ifparm.u.bt656.clock_curr == 0) {

                csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;

            } else {

                if (cam->device_type != 1)

                    csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;

                else

                    csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE;

            }

            if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_8;

            } else if (ifparm.u.bt656.mode

                    == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_10;

            } else {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_8;

            }

            csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;

            csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;

            csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;

            csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;

        } if (ifparm.if_type == V4L2_IF_TYPE_BT1120) {

            {

                if (ifparm.u.bt1120.clock_curr == 0) {

                    csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR;

                }

 else {

                    if (cam->device_type != 1)

                        csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;

                    else

                        csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR;

                }

            }

            if (ifparm.u.bt1120.mode == V4L2_IF_TYPE_BT1120_MODE_BT_8BIT) {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_8;

            } else if (ifparm.u.bt1120.mode

                    == V4L2_IF_TYPE_BT1120_MODE_BT_16BIT) {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_16;

            } else {

                csi_param.data_width = IPU_CSI_DATA_WIDTH_8;

            }

            csi_param.Vsync_pol = ifparm.u.bt1120.nobt_vs_inv;

            csi_param.Hsync_pol = ifparm.u.bt1120.nobt_hs_inv;

            csi_param.pixclk_pol = ifparm.u.bt1120.latch_clk_inv;

            csi_param.ext_vsync = ifparm.u.bt1120.bt_sync_correct;

        }

 

4.6   adv7441a_probe函数

 

static int adv7441a_probe(struct i2c_client *client,

                const struct i2c_device_id *id)

{

        int ret = 0;

        tvin_plat = client->dev.platform_data;

        if (tvin_plat->io_init)

                tvin_plat->io_init();

        if (tvin_plat->reset)

                tvin_plat->reset();

        if (tvin_plat->pwdn)

                tvin_plat->pwdn(0);

        msleep(1);

        /* Set initial values for the sensor struct. */

        memset(&adv7441a_data, 0, sizeof(adv7441a_data));

        adv7441a_data.sen.i2c_client = client;

        adv7441a_data.sen.streamcap.timeperframe.denominator = 30;

        adv7441a_data.sen.streamcap.timeperframe.numerator = 1;

        adv7441a_data.std_id = V4L2_STD_ALL;

        video_idx = ADV7441A_NOT_LOCKED;

        adv7441a_data.sen.streamcap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;

        adv7441a_data.sen.pix.width = video_fmts[video_idx].raw_width;

        adv7441a_data.sen.pix.height = video_fmts[video_idx].raw_height;

 adv7441a_data.sen.pix.pixelformat = V4L2_PIX_FMT_YUYV; //像素格式

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

        adv7441a_data.sen.on = true;

        adv7441a_data.sen.csi = 1;

}

4.7   V4L从设备给V4L主设备的获取时序模式参数的函数

static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)

{

        if (s == NULL) {

                pr_err("   ERROR!! no slave device set!\n");

                return -1;

        }

        /* Initialize structure to 0s then set any non-0 values. */

        memset(p, 0, sizeof(*p));

        p->if_type = V4L2_IF_TYPE_BT1120;/* This is the only possibility. */

        p->u.bt656.mode = V4L2_IF_TYPE_BT1120_MODE_BT_8BIT;

        p->u.bt656.clock_curr = 1;

        return 0;

}

 

4.8   V4L从设备给V4L主设备的获取分辨率的函数

 

static int ioctl_enum_framesizes(struct v4l2_int_device *s,

                struct v4l2_frmsizeenum *fsize)

{

        if (fsize->index >= 1)

                return -EINVAL;

                fsize->discrete.width = (hdmi_read(0x07) & 0x0f) * 256 + hdmi_read(0x08);

                fsize->discrete.height = (hdmi_read(0x09) & 0x0f) * 256 + hdmi_read(0x0a);

                adv7441a_autoset(fsize->discrete.width, fsize->discrete.height);

                fsize->discrete.height -= (fsize->discrete.height) % 8;

        return 0;

}

 

转载于:https://www.cnblogs.com/arm-cd/p/3493043.html


http://www.ppmy.cn/news/272674.html

相关文章

rk3399 调试一款新的摄像头驱动

rk3399 mipi camera Firefly-RK3399 开发板分别带有两个 MIPI,一个 DVP 摄像头接口 rk3399平台可以支持多种不同接口的Camera,如MIPI, DVP, UVC,USB camera 对于DVP,MIPI接口的,是在cam_board.xml文件注册camera,isp控制器接收 对于UVC,USB接口的只要移…

图片处理PIL.Image模块

Image模块是PIL中最重要的模块,它有一个类叫做image,与模块名称相同。Image类有很多函数、方法及属性,接下来将依次对image类的属性、函数和方法进行介绍。 一、Image类的属性 1、 Format 定义:im.format ⇒ string or None 含…

RK平台USB摄像头FAQ

(记录android9以后调试所遇到的常见问题,有错请批评指正) UVC全称为USB video(device) class,是微软与另外几家设备厂商联合推出的为usb视频捕获设备定义的协议标准;所以说UVC仅仅是usb规范协议中设备类规范…

机器视觉项目 - 选型总结

一. 面阵相机和镜头选型 已知:被检测物体大小为A*B,要求能够分辨小于C,工作距为D 解答: 1. 计算短边对应的像素数 E B/C,相机长边和短边的像素数都要大于E; 2. 像元尺寸 物体短边尺寸B / 所选相机的短边像素数&…

ESP32-CAM之ST7789图像显示

ESP32-CAM之ST7789 最近笔者在学习使用安信可的ESP32-CAM开发板,该开发板自带一个OV2640摄像头。 官方提供的例程可以将摄像头视频通过WIFI传输到网页显示,而笔者手里正好有一块240x240像素的屏幕,便想将摄像头的图像显示到该屏幕上。 从es…

【软考笔记】9. 多媒体基础

文章目录 基本概念音频声音的带宽声音的采样采样频率采样精度 图像亮度色调饱和度彩色空间RGB:彩色显示器YUV(YIQ YCBCR):电视CMY(CMYK):印刷HSV(HSB):艺术家…

Google bot能够执行Javascript,Google bot的分辨率是1600x1200

如图,Google搜索“js 播放器 支持 ipad”: 我用js做了一个字号自动放大功能,检测到用户的浏览器分辨率,然后设置字号。用js innerHTML一段提示显示分辨率。 今天突然发现此js提示出现在Google搜索结果中,显示Google bo…

Stm32标准库函数5——摄像头OV2640 F103C8T6 串口显示高分辨率图像640x480 1024x768 1024x1024 1600x1200 二百万像素

stm32f103c8t6串口发送 OV2640的图像,分辨率可选。网络上资料大部分是低分辨率的,这个可以做高分辨率 完整工程打包,包含VB串口显示界面: Stm32标准库函数5-OV2640PA0-7F103C8T64500000联合VB高分辨率资源-单片机文档类资源-CSDN…