原创 i.MX27视频应用技术详解-TW2835

2011-10-11 12:22 1507 6 6 分类: 消费电子

             简解要介绍mx27中强大的视频处理功能

 

    Freescale公司出品的mx27芯片,秉承了欧美系芯片产商内部资源丰富,性能稳定可靠的设计原则。其中最为耀眼的功能就是其使用简单却又功能强大的视频处理单元。其内部的视频处理部分共有3个模块,分别

 

1.CMOS Sensor Interface 可以直接接传统的CMOS摄像头接口,也可以接CCIR视频接口,这是负责视频的采集接口部分

2.内部集成了增强型低功耗的多媒体加速器eMMA,可以进行视频的前预处理和后处理以及类似去环块(dering),色彩空间转换,放大和图像的平滑缩放等,这是视频的前后期处理部分.

3.内置硬件编解码模块,支持H.264/MPEG4硬件编解码,全双工不占用CPU资源。

 

我们先来介绍视频的采集和预处理部分。

视频采集芯片我们采用的是可以支持4路视频输入的TW2835。可以达到D1的视频效果,完全满足基本的视频监控需求

    Techwell公司推出了 TW2835 四信道视频和音频控制器。建立在 TW2834 的成功基础之上,TW2835 将6个主要程序整合进一个芯片中,其中包括:4个高质量的 NTSC/PAL 视频解码器、4个音频模拟数字转换器、一个音频复用器,双色显示控制器,双视频译码器以及一个先进的 OSD(屏幕菜单式调节方式)。此外,TW2835 每个芯片还使用了一个单一的同步动态存储器 (SDRAM),可用于可选的 BGA 包中,还拥有一个被称为 TW2836 的 pin-to-pin(管脚到管脚)姊妹芯片。TW2836 除了不包含音频之外,与 TW2835 具有同样的功能。TW2835 利用了 Techwell 安全监控集成电路产品解决方案的广泛组合,是帮助 DVR(数码视频录像机)生产商提高质量与功能、加快上市时间以及减少成本的重要一步。在其众多功能中,TW2835 支持详尽的实时 D1 录制、在重放过程中将信道 ID 信息添加到视频流媒体中,用于自动解码与显示,同时还包含一个5层的图形覆盖功能,为 OSD、单盒、2D 阵列箱以及鼠标指示器显示特征/位图。TW2835 还包含一个简单的界面,使用多段连接支持多达16个信道系统。此外,TW2835 还嵌入了几种特别的监视功能,其中包括:运动监测、放大以及水平与垂直缩放控制。凭借置入旨在减少交叉噪音的反锯齿过滤器和高质量的梳状过滤器,TW2835 已经成为一种针对 DVR 与 Quad/Multiplexers 的高性能、具有成本效益的解决方案。

    tw2835比较灵活,既可以单路切换采集4路D1视频,也可以将4路视频集成到1路D1视频输出,可以根据你的需求在应用程序上控制。成都莱得科技(www.nidetech.com)提供的驱动程序给应用程序提供了控制接口。并且提供完整的驱动程序源代码,该方案和代码在客户的实际产品中获得了成功的验证。现在我们简要的介绍一下tw2835在mx27开发板中的驱动编写和遇到的一些问题。

   

    一、驱动的架构和实现

   

    tw2835和mx27的视频流传输是通过mx27的CSI接口,命令控制接口采用I2C

也就是是说驱动分为两个部分

  1. i2c驱动:

负责初始化和配置芯片,例如设置和获取颜色,复位芯片,设置通道属性,检测芯片的存在与否,设置csi接口的时钟等

   

  //驱动初始化

    static __init int tw2835_init(void)

    {

             u8 err;

 

             gpio_tw2835_active();

 

             err = i2c_add_driver(&tw2835_i2c_driver);

             return err;

    }

 

    //首先要对硬件引脚功能进行初始化,

    void gpio_tw2835_active(void)

{

 

//设置CSI接口的引脚功能

         gpio_request_mux(MX27_PIN_CSI_D0, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D1, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D3, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D4, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_MCLK, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_PIXCLK, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D5, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D6, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_D7, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_VSYNC, GPIO_MUX_PRIMARY);

         gpio_request_mux(MX27_PIN_CSI_HSYNC, GPIO_MUX_PRIMARY);

 

 

         /* Power down control */

         mdelay(10);

         gpio_request_mux(MX27_PIN_USBH1_RXDM, GPIO_MUX_GPIO);

         mxc_set_gpio_direction(MX27_PIN_USBH1_RXDM, 0);

         mxc_set_gpio_dataout(MX27_PIN_USBH1_RXDM, 1);

 

         /* Reset芯片 */

         mdelay(10);

         gpio_request_mux(MX27_PIN_CSPI1_RDY, GPIO_MUX_GPIO);

         mxc_set_gpio_direction(MX27_PIN_CSPI1_RDY, 0);

         mxc_set_gpio_dataout(MX27_PIN_CSPI1_RDY, 0);

         mdelay(10);

         mxc_set_gpio_dataout(MX27_PIN_CSPI1_RDY, 1);

         mdelay(10);

 

}

 

然后,进行调用i2c驱动接口,i2c_add_driver ,加入新的驱动。由框架自动调用attach函数

在该函数中,设定tw2835的主时钟,然后调用i2c_probe进行芯片的地址检测

static int tw2835_attach(struct i2c_adapter *adap)

{

         uint32_t mclk = 27000000;

         struct clk *clk;

         int err;

 

         clk = clk_get(NULL, "csi_clk");

         clk_enable(clk);

         set_mclk_rate(&mclk);

 

         err = i2c_probe(adap, &addr_data, &tw2835_detect_client);

         clk_disable(clk);

         clk_put(clk);

 

         return err;

}

在扫描到芯片的地址和预置的地址一致的时候,调用tw2835_detect_client

该函数

 

   

   

#define TW2835_I2C_ADDRESS      0x42 //tw2835的i2c地址

#define TW2835_DEVICE_ID  0x05 //芯片内部的id,从寄存器中读出

 

1.调用i2c_attach_client将adapter设置到tw2835_i2c_client中

2.将tw2835_i2c_client加入到i2c设备列表中去

3.分配一个摄像头接口数据,设置主时钟

static int tw2835_detect_client(struct i2c_adapter *adapter, int address,

                                      int kind)

{

         tw2835_i2c_client.adapter = adapter;

         if (i2c_attach_client(&tw2835_i2c_client)) {

                   tw2835_i2c_client.adapter = NULL;

                   printk(KERN_ERR "tw2835_detect_client: i2c_attach_client failed\n");

                   return -1;

         }

  

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条