zynq 实现液晶显示器显示(ADV7511)

      首先来明确下设计结构,不管是用HDMI,VGA还是DP,最重要的过程是把帧缓冲中的RGB数据转换成显示扫描时序。显示扫描时序这个词并不存在于显示行业,只是我认为这样说能概括问题。

     来解释下显示扫描时序。先说几个名词,之后会用上:

1、像素时钟(CLK):屏幕上每个像素点显示动态显示都需要像素时钟来刷新;

2、行同步时钟(HSYNC):当显示器显示一行像素的时间;

3、场同步时钟(VSYNC):显示器显示一帧内容的时间;

4、像素数据(data):每个像素点的原始RGB数据;

     找两张图来解释下:

        就这样吧,重点不在这里。为什么要写这么点?我觉得恰到好处,不会的人可以得到提示去专门学一下显示控制器的相关知识。会的人也不想看太多。同智的内容看起来舒服,但是不会有成长。

       PL部分的实现:

这是显示控制器的IP核,可以在ADI官网找到。注意下输入信号:

1、S_AXI是利用AXI_LITE对该控制器进行一些寄存器相关的配置。

2、hdmi_clk就是像素时钟;

3、vdma_clk是和VDMA控制器同步的时钟;

4、vdma_data是链接dma控制器输出端,也是该模块的原始数据输入;

输出信号就是之前讲的显示扫描时序,你可以在物理层接HDMI传输器,或者直接接RGB显示器。

 

VDMA控制器:

先看信号含义:

1、S_AXI_LITE同样是完成该控制器配置的;

2、mm2s_fsync:帧同步

3、M_AXI_MM2S:DMA数据来源;

4、M_AXI_MM2S:DMA数据流出;

 

以上是部分的连接图,尝试了好多次都没有好办法把矢量图粘贴上来。有需要可以邮箱联系我 yhl@onetek.net  tcl脚本后再github发布。

好了,到这一步,PL部分基本完成。来看下地址分配。这个很重要,之后无论是裸金属操作还是搭载操作系统,中断号和控制器地址永远是最重要的,地址信息如下:

中断号:

完成了PL部分设计以后,开始转向PS设计。

PS会统筹所用PL以及硬件资源,最后实现内容的显示。

以上连接在zynq上的ADV7511。

1、除了视频控制信号以外,还需要一路IIC对该器件进行一些配置。因此PS代码中应该有ADV7511的初始化代码;

2、在PL总的连接图可以看出,显示控制器需要一路clk_gen,该信号受AXI总线控制;

3、视屏控制器以及VDMA,这部分代码是显卡驱动程序;

根据以上所分析的,来对设备树进行修改:

/ {
	fpga_axi: fpga-axi@0 {
		compatible = "simple-bus";
		#address-cells = <0x1>;
		#size-cells = <0x1>;
		ranges;

		i2c@41600000 {
			compatible = "xlnx,axi-iic-1.02.a", "xlnx,xps-iic-2.00.a";
			reg = <0x41600000 0x10000>;
			interrupt-parent = <&intc>;
			interrupts = <0 58 4>;
			clocks = <&clkc 15>;
			clock-names = "pclk";

			#address-cells = <1>;
			#size-cells = <0>;

			i2c_mux: i2cswitch@74 {
				compatible = "nxp,pca9548";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x74>;

				i2c@0 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <0>;
					osc@5d {
						compatible = "si570";
						temperature-stability = <50>;
						reg = <0x5d>;
						factory-fout = <156250000>;
						initial-fout = <148500000>;
					};
				};

				i2c@1 {
				    #address-cells = <1>;
				    #size-cells = <0>;
				    reg = <1>;

				    adv7511: adv7511 {
						compatible = "adi,adv7511";
						reg = <0x39>, <0x3f>;
						reg-names = "primary", "edid";

						adi,input-depth = <8>;
						adi,input-colorspace = "rgb";
						adi,input-clock = "1x";
						adi,clock-delay = <0>;

						#sound-dai-cells = <0>;

						ports {
							#address-cells = <1>;
							#size-cells = <0>;

							port@0 {
								reg = <0>;
								adv7511_in: endpoint {
									remote-endpoint = <&axi_hdmi_out>;
								};
							};

							port@1 {
								reg = <1>;
							};
						};
				    };
				};

				i2c@2 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <2>;
					eeprom@54 {
						compatible = "at,24c08";
						reg = <0x54>;
					};
				};

				i2c@3 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <3>;
					gpio@21 {
						compatible = "ti,tca6416";
						reg = <0x21>;
						gpio-controller;
						#gpio-cells = <2>;
					};
				};

				i2c@4 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <4>;
					rtc@54 {
						compatible = "nxp,pcf8563";
						reg = <0x51>;
					};
				};
			};
		};

		axi_vdma_0: axivdma@43000000 {
			#address-cells = <1>;
			#size-cells = <1>;
			#dma-cells = <1>;
			compatible = "xlnx,axi-vdma-1.00.a";
			reg = <0x43000000 0x1000>;
			xlnx,num-fstores = <0x3>;
			dma-channel@43000000 {
				compatible = "xlnx,axi-vdma-mm2s-channel";
				interrupts = <0 59 0x4>;
				xlnx,datawidth = <0x40>;
				xlnx,genlock-mode = <0x0>;
				xlnx,include-dre = <0x0>;
			};
		};

		hdmi_clock: axi-clkgen@0x43C10000 {
			compatible = "adi,axi-clkgen-2.00.a";
			reg = <0x43C10000 0x10000>;
			#clock-cells = <0>;
			clocks = <&clkc 16>;
		};

		axi_hdmi@0x43C00000 {
			compatible = "adi,axi-hdmi-tx-1.00.a";
			reg = <0x43C00000 0x10000>;
			dmas = <&axi_vdma_0 0>;
			dma-names = "video";
			clocks = <&hdmi_clock>;
			adi,is-rgb;

			port {
				axi_hdmi_out: endpoint {
					remote-endpoint = <&adv7511_in>;
				};
			};
		};

	//	axi_spdif_tx_0: axi-spdif-tx@75c00000 {
	//		compatible = "adi,axi-spdif-tx-1.00.a";
	//		reg = <0x75c00000 0x1000>;
	//		dmas = <&dmac_s 0>;
	//		dma-names = "tx";
	//		clocks = <&clkc 15>, <&audio_clock>;
	//		clock-names = "axi", "ref";
 
	//		#sound-dai-cells = <0>;
		};
	};

	audio_clock: audio_clock {
		compatible = "fixed-clock";
		#clock-cells = <0>;
		clock-frequency = <12288000>;
	};

	adv7511_hdmi_snd {
		compatible = "simple-audio-card";
		simple-audio-card,name = "HDMI monitor";
		simple-audio-card,widgets =
			"Speaker", "Speaker";
		simple-audio-card,routing =
			"Speaker", "TX";

		simple-audio-card,dai-link@0 {
			format = "spdif";
			cpu {
				sound-dai = <&axi_spdif_tx_0>;
				frame-master;
				bitclock-master;
			};
			codec {
				sound-dai = <&adv7511>;
			};
		};
	};
};

设备树的修改比较容易,就是根据之前PL部分的地址已经中断号。IIC控制器的设备树要结合自己的硬件平台来进行修改,我这里使用的是软核IIC控制器+IIC多路器来对adv7511进行控制。

       在调试的时候要首先关注这里,CPU通过IIC控制器会读取液晶显示器的EDID,该驱动程序注册了debugfs,可以直接查看到设备的edid以及时钟等信息。debugfs使用如下:

1、配置内核,使其支持debugfs   Kernelhacking --->[*]Debug Filesystem;

2、mount -t debugfs none /mnt;

3、打开挂在的目录;

HDMI识别显示器的过程有必要啰嗦一下。当显示器连接到HDMI connector 上时,已有一个hotplug信号。该信号表征HDMI显示器已经连接,硬件测试时候要关注该信号。当ADV7511拿到该信号以后,就开始读取液晶显示器的EDID,(EDID就是告诉显示控制器自己的信息,比如分辨率,backsacn time等)。显示控制器拿到这些信息以后,显示控制器会发出与之匹配的信号。

如果这一步没有问题,示波器就能够测量到clk,hsync,vsync信号,显示器就可以正常工作。

 

 

 

 

 

 

 

 

 

 

  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Zynq是一款基于Xilinx公司的可编程逻辑器件(FPGA)和ARM处理器的系统级集成芯片(SoC),它提供了高度灵活的硬件和软件协同设计的能力。 要实现AM调制,可以利用Zynq的可编程逻辑器件部分来实现调制器的设计。在可编程逻辑器件中,我们可以使用硬件描述语言(如Verilog或VHDL)来描述AM调制器的功能并进行实现。通过定义适当的模块来生成调制信号,并将其传递给数字信号处理模块,使用模拟调制技术将基带信号和载波信号进行混合。 Zynq还提供了ARM处理器的部分,可以通过软件实现AM调制的控制和处理。通过编写C语言或其他高级语言的程序,我们可以利用ARM处理器来控制调制器的运行、参数调整等功能。另外,我们还可以利用Zynq内置的外设接口(如GPIO、UART、SPI等)与外部设备进行通信,实现与其他模块的数据传输和控制。 此外,Zynq的并行处理能力和高速数据传输功能,可以帮助实现实时的AM调制处理。通过合理的设计和优化,我们可以在Zynq的硬件和软件协同设计中实现高效的AM调制系统,并满足不同应用场景的要求。 总的来说,利用Zynq的可编程逻辑器件和ARM处理器的综合优势,可以实现灵活、高效的AM调制系统。通过合理的硬件和软件设计,结合Zynq的特性和外设接口,可以满足不同应用场景下对AM调制的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值