全志平台boot里TVD倒车显示功能开发

 全志平台boot里TVD倒车显示功能开发

 

        倒车显示分两个部分,前端处理好视频输入信号,准备好内容,后端显示驱动再来把内容显示到LCD上。很明显,前端是TVD模块来处理的,后端是有DE模块来处理的,我们接下来先分析一下TVD模块怎么工作的。

      首先,需要加载驱动打开设备驱动,如果有需要还可以执行IOCTL操作,跟在linux系统里操作驱动的IOCTL类似。代码如下:

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

	ret = wBoot_driver_install("c:\\drv_tvd.drv");
	if(ret != 0)
	{
		DMSG_PANIC("ERR: wBoot_driver_install drv_tvd driver failed\n");
		return -1;
	}

    ret = wBoot_script_parser_fetch("tvin_para", "tvin_reverse_channel_num", &reverseChannel, 1);
	if(ret)
	{
		__inf("unable to find tvin_para tvin_reverse_channel_num value\n");
	}

	__inf("BoardInit_TVD: reverseChannel=%x\n", reverseChannel);
	TVDTransferToDRVInfo.ch = reverseChannel;
	//open tvd devices , we transfer some TVD parameter to driver
	tvd_hd = wBoot_driver_open(EGON2_EMOD_TYPE_DRV_TVD, &TVDTransferToDRVInfo);
	if(tvd_hd == NULL)
	{
		DMSG_PANIC("ERR: open drv_tvd driver failed\n");
		return -1;
	}

       加载驱动会执行到init接口,打开设备的时候会执行open接口,对应接口在上一篇文章中有介绍到。那么,我们可以再open的接口里对TVD    模块做一些必要的设置,当然一些模块的参数,我们可以再open的时候传给TVD的驱动,也就是传给DRV_TVD_OPEN函数接口。笔者根据需要传了一些控制参数进去,比如选择的TVD channel通道号,因为TVD有4个channel;显示的视频信号格式是NTSC信号还是PAL的信号,这样可以加快初始化,加快出正确的图像;以及Y/C的buffer地址,这里是为了让display这边方便的拿到显示buffer的地址,当然申请buffer放到TVD驱动里也是可以的,但是对应显示驱动就得晚于TVD驱动执行,这个问题其实也有人写一个固定的安全内存地址,其实也可以,只是感觉不灵活。

      下面就说说TVD的具体驱动,首先TVD需要设置的是CLK,没有CLK什么都是扯,主要是ahb bus、tvd模块、DRAM、PLL3  VIDEO相关的clock,大致如下:

	ccm_clock_disable(TVD_CKID);
	ccm_clock_enable(TVD_CKID);
	set_wbit(CCM_DRAMCLK_GATE_CTRL, 0x1U<<4);//tvd
	if(mode<4)
	{
		put_wvalue(CCM_PLL3_VIDEO_CTRL,0x80105000);
		put_wvalue(CCM_TVD_SCLK_CTRL,0x8000800a);
	}
	else
	{
		put_wvalue(CCM_PLL3_VIDEO_CTRL,0x8010905a);
		put_wvalue(CCM_TVD_SCLK_CTRL,0x80008004);
	}

void ccm_clock_enable(u32 clk_id)
{
	switch(clk_id>>8) {
		case AXI_BUS:
			set_wbit(CCM_AXI_GATE_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case AHB_BUS0:
			set_wbit(CCM_AHB_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case AHB_BUS1:
			set_wbit(CCM_AHB_GATE1_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case APB0_BUS0:
			set_wbit(CCM_APB0_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case APB1_BUS0:
			set_wbit(CCM_APB1_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
	}
}

void ccm_clock_disable(u32 clk_id)
{
	switch(clk_id>>8) {
		case AXI_BUS:
			clr_wbit(CCM_AXI_GATE_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case AHB_BUS0:
			clr_wbit(CCM_AHB_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case AHB_BUS1:
			clr_wbit(CCM_AHB_GATE1_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case APB0_BUS0:
			clr_wbit(CCM_APB0_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
		case APB1_BUS0:
			clr_wbit(CCM_APB1_GATE0_CTRL, 0x1U<<(clk_id&0xff));
			break;
	}
}

        接着就是控制TVD模块具体的寄存器了,使能必不可少,IRQ设置不可少,对比度、亮度、饱和度等,当然还有其他的一堆,初步的值是全志提供的,但是为了更好的显示效果,主要是匹配你这个产品的屏参吧,那我们就看一段NTSC的参数吧!

 

		put_wvalue( TVD_BASE + 0x0008, 0x00590900); //notch width 0059_0100
		put_wvalue( TVD_BASE + 0x000c, 0x00000010); //YC sep
		put_wvalue( TVD_BASE + 0x0010, 0x008A32DD); //sync height
		put_wvalue( TVD_BASE + 0x0014, 0x800000a0); //adjust YC delay
		put_wvalue( TVD_BASE + 0x0018, 0x00002080); //adjust luma brightness
		put_wvalue( TVD_BASE + 0x001c, 0x008a0080); //chroma AGC target
		put_wvalue( TVD_BASE + 0x0024, 0x0682810a); //DISABLE AGC GATE KILL!!!!!!!!!!!!!!!!!
		put_wvalue( TVD_BASE + 0x0028, 0x00006440); //0000_6440    0000_5838
		put_wvalue( TVD_BASE + 0x0034, 0x20000000); //2000_0000    2400_0000
		put_wvalue( TVD_BASE + 0x0044, 0x50824632); //burst gate
		put_wvalue( TVD_BASE + 0x004c, 0x0e70106c); //NO CLAMP DURING VSYNC!!!!!!!!!!!!!!!!!
		put_wvalue( TVD_BASE + 0x0054, 0x00000025); //peak en
		put_wvalue( TVD_BASE + 0x006c, 0x00fffa0a); //YC separation config
		put_wvalue( TVD_BASE + 0x0080, 0x00500082); //hactive start and width
		put_wvalue( TVD_BASE + 0x0084, 0x00610022); //vactive start and height
		put_wvalue( TVD_BASE + 0x0030, 0x21f07c1f); //21f0_7c1f    262E_8BA2
		put_wvalue( TVD_BASE + 0x002c, 0x0000CB74);
		put_wvalue( TVD_BASE + 0x0074, 0x000003c3); //chroma edge enhance
		put_wvalue( TVD_BASE + 0x050c, 0x0000000b);
		put_wvalue( TVD_BASE + 0x051c, 0x00100000);

	put_wvalue( TVD_BASE + 0x0134 + ch * 0x100, y<<16 | x);
	put_wvalue( TVD_BASE + 0x0138 + ch * 0x100, len);

	put_wvalue( TVD_BASE + 0x0100 + ch * 0x100, addr0);
	put_wvalue( TVD_BASE + 0x0110 + ch * 0x100, addr1);
	put_wvalue( TVD_BASE + 0x0104 + ch * 0x100, addr2);
	put_wvalue( TVD_BASE + 0x0114 + ch * 0x100, addr3);
	put_wvalue( TVD_BASE + 0x0108 + ch * 0x100, addr4);
	put_wvalue( TVD_BASE + 0x0118 + ch * 0x100, addr5);
	put_wvalue( TVD_BASE + 0x010c + ch * 0x100, addr6);
	put_wvalue( TVD_BASE + 0x011c + ch * 0x100, addr7);
	put_wvalue( TVD_BASE + 0x0130 + ch * 0x100, frame<<26   | is_mb<<24 |       \										hsample<<12 | is_yuv422<<4 | 0x1);

        put_wvalue(TVD_BASE+0x0148,0xf1ffffff);//int//int en//frame end, overflow, underflow
        put_wvalue(TVD_BASE+0x0140,0xffffffff);//clear irq//frame end, overflow, underflow
        put_wvalue(TVD_BASE+0x014c,0xffffffff);//address change error
        put_wvalue(TVD_BASE+0x0150,0x00000000);//int en//lock unlock
        put_wvalue(TVD_BASE+0x0154,0x0000ffff);//clear irq//lock unlock

        这些程序一走,数据就差不多出来了。那么接下来就准备显示吧!

       显示这部分在boot里面也已经是支持了的,但是需要自己去改造成自己需要的。首先模块的初始化还是借用boot里面已经支持的BoardInit_Display()接口,除此之前就需要自己动手来做了。比如要设置显示layer具体参数,比如显示的宽高、buffer的地址、显示的格式、是否是UV combined模式等,也不少。除此之外还得打开layer,因为申请layer已经在BoardInit_Display()接口里完成了。笔者的NTSC的显示参数大致如下:

		memset((&layer_para), 0, sizeof(layer_para));
		layer_para.fb.size.width		= 704;
		layer_para.fb.size.height		= 480;
		layer_para.fb.addr[0]			= (__u32)TVDTransferToDRVInfo.addrYx;//TVD_ADDR_Y0;
		layer_para.fb.addr[1]			= (__u32)TVDTransferToDRVInfo.addrCx;//TVD_ADDR_C0;
		layer_para.fb.mode = DISP_MOD_NON_MB_UV_COMBINED;
		layer_para.fb.format = DISP_FORMAT_YUV422;
		layer_para.fb.br_swap = 0;
		layer_para.fb.seq = DISP_SEQ_UYVY;
		layer_para.ck_enable		= 0;
		layer_para.mode 		  = DISP_LAYER_WORK_MODE_SCALER;
		layer_para.alpha_en 	  = 1;
		layer_para.alpha_val	  = 0xff;
		layer_para.pipe 		  = 0;
		layer_para.src_win.x	  = 15;
		layer_para.src_win.y	  = 10;
		layer_para.src_win.width  = 688;
		layer_para.src_win.height = 470;
		layer_para.scn_win.x	  = 0;
		layer_para.scn_win.y	  = 0;
		layer_para.scn_win.width  = De_GetSceenWidth();
		layer_para.scn_win.height = De_GetSceenHeight();

        通过以上的简单分析,倒车显示是基本OK了。但是记得退出倒车的时候要关闭显示,关闭TVD,卸载对应驱动。到此,基本上整个过程就分析完了。

 

时间: 2024-10-21 12:13:37

全志平台boot里TVD倒车显示功能开发的相关文章

全志平台boot框架中增加设备驱动过程分析

全志平台boot框架中增加设备驱动过程分析          在boot启动阶段,大家都知道他的主要目的就是引导uboot,uboot在引导内核,从而让整个系统运作起来.全志的boot阶段,对应平板这一块,它会驱动LCD,显示一些开机LOGO,这个过程很快,也就1-2秒钟的时间.然而对于车载行业应用来说,可能需要再boot阶段做一些事情.比如,机器冷启动,大家都知道android启动时间还是比较长的,那么怎么使得客户能快速的用上倒车影像的功能呢?这就需要动脑筋了. /**************

color key在倒车显示功能上的至关重要性

 color key在倒车显示功能上的至关重要性      随着经济的高速发展,汽车越来越多了,在城市里停车位越来越难找,停车位也越来越小,这时候倒车技术就显得非常重要了,左边是宝马,右边是奥迪,车位后面还可能有行人走的场景那就太可怕了,哪个都惹不起啊,这种情况下是不是有一个倒车影像是不是更好呢,答案当然是肯定的,可以看得更清楚,辅助倒车更安全,现在这个功能在小汽车上至少在半数以上都装了吧!     倒车影像是个好东西,那怎么实现,怎么弄出一个相当棒的倒车图像显示效果呢?倒车一般分两种,一种就是

uboot里开机LOGO显示功能解析

 uboot里开机LOGO显示功能解析     开机LOGO,对于绝大多数带显示屏的电子产品都是必备的一个功能,是产品开机的第一印象,重要性不言而喻的,那我们下面就看看这个是怎么实现的.    要尽早的显示出LOGO就需要在系统真正起来之前的boot阶段就能打通显示,而这个任务大多是以U-BOOT这样的角色来充当,全志平台在android4.4平台就是在u-boot里面实现的,支持的是BMP图片.大家分为几个步骤了,首先要读取图片,再解析图片数据,然后再送到显示部分,最后显示出来.事就是这么个事

全志平台Android4.0预装媒体资源文件文件

  全志平台Android4.0预装媒体资源文件        最近开发来了一个小需求:在发布的软件包里面预装一些多媒体资源文件.想起来,挺容易的,不就是把多媒体文件拷贝到系统里面去吗?是的,确实是这样,可是得在不同开发平台做法不大一样,目前全志软件打包升级工具还没有很完善,只是在卡启动的做卡程序里可以在烧卡的时候预装一些媒体资源文件.    在文件管理器访问的路径是/mnt/sdcard这个挂载点是管理了nand用户数据区域的,可以通过USB连到电脑拷贝.删除文件.但是这是一个挂载点,并且是在

分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

一起谈.NET技术,分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

微信公众平台文章里怎么实施一键拨号?

问题描述 微信公众平台文章里怎么实施一键拨号? 求大神们指导......还有用什么可以写代码?怎么把代码做成链接的? 解决方案 微信后台加不了连接...

源码-做安卓驱动工程师 选用 全志平台 还是 MTK平台 ?哪个好?

问题描述 做安卓驱动工程师 选用 全志平台 还是 MTK平台 ?哪个好? MTK平台: mtk公司已经把Android源码优化了,把相关的驱动代码放到 mediatek 目录下, 主要修改相关的驱动就行,这样工程师跟内核的交互就少了,久而久之就不太熟悉 平台设备驱动等等: 全志平台: 我还没深入了解过. 有哪位大神对这两个平台比较了解, 做安卓驱动工程师 , 选择那款平台深入比较好? 解决方案 MTK挺好啊,高通平台也不错,全志平台没用过. 不过你做 android驱动工程师,如果不是 要做 平

Oracle平台应用数据库系统的设计与开发_oracle

正在看的ORACLE教程是:Oracle平台应用数据库系统的设计与开发.Oracle是目前应用最广泛的数据库系统.一个完整的数据库系统包括系统硬件.操作系统.网络层.DBMS(数据库管理系统).应用程序与数据,各部分之间是互相依赖的,对每个部分都必须进行合理的配置.设计和优化才能实现高性能的数据库系统.本文讨论笔者使用Oracle开发局域网中.小型数据库应用中,系统硬件的选择与使用.应用数据库系统设计与开发方面的一些心得和建议.应用数据库系统包含应用数据库和应用两方面的内容,应用数据库就是生产数