3. ZCU102 HDMI Demo工程修改【PCIE视频传输】

为了更快速的开发我需要的带缓存的hdmi收发通路,将上一节的demo进行修改来实现。当然,可以从头开始自己进行配置,我就这么做了,但是因为fpga配置的不同,还要修改更多的驱动代码,相当麻烦,所以就直接拿demo的工程来用吧。(我一开始参考了TRD的工程代码,跟hdmi demo的配置还是有区别的,比如RX通道的参考时钟,TRD用了SI5324的晶体,而demo用的是fpga输出的时钟)。

1 Vivado 工程修改

将上节的zcu102 hdmi demo工程打开,选择File -> Save Projeject As
将名称设置为zcu102_hdmi_frame
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第1张图片

打开block design
因为不使用音频功能,所以将audio相关的连接和模块删除。删除前参考TRD的设计,可以看到v_hdmi_tx_ss的s_axis_audio_aclk和s_axis_audio_aresetn需要进行连接,其他的直接删除或接0即可。
删除下面的模块。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第2张图片
将tx和rx的s_axis_audio_aresetn和fid信号连线删除。将s_axis_audio_aclk连接到s_axi_cpu_aclk。

添加Video Mixer IP
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第3张图片
双击IP进行配置
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第4张图片

添加Video Frame Buffer Write IP
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第5张图片
双击进行配置,视频格式选择了RGB8、YUV8、YUYV三种常见的HDMI视频格式。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第6张图片

添加AXI Data FIFO IP
双击进行配置,将数据带宽改为128,Write FIFO Depthe设置为512,delay设置为ON。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第7张图片

将v_tpg_ss_0这个结构改名为v_dma_ss,然后将刚才添加的这些IP都拖进来。
双击结构中的v_tpg,将所有功能勾选。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第8张图片
双击结构中的axi_gpio,将GPIO Width改为3。结构中的tpg、mix、frmbuf_wr都需要用GPIO来实现异步复位,这是官方Linux驱动的要求,就按照它的办吧。当然不用linux的话也可以将这些复位管脚接到reset模块。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第9张图片
然后添加3个slice分别定位到0、1、2位,分别连接到tpg、mix、frmbuf_wr模块。

双击zynq ps,添加两个主AXI HPM FPD和两个从AXI HP FPD。第一个主接口用来低速的AXI外设配置(100MHz),第二个主接口用来高速的AXI外设配置(300MHz);第一个从接口用来实现HDMI TX通道数据读取(300MHz),第二个从接口用来实现HDMI RX通道数据写入(300MHz)。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第10张图片
在zynq_us_ss_0中添加AXI Interconnect IP

添加AXI Interconnect IP
双击进行配置,4输入1输出,Max Performence,Enable Register Slice, Enable Data FIFO
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第11张图片
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第12张图片
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第13张图片
再添加一个AXI Interconnect IP,1输入1输出,其它配置跟前边的相同。

再添加一个AXI Interconnect IP,1输入4输出,选择Minimal Area,Enable Register Slice选择Outer,Enable Data FIFO选择NONE
将原有的一个AXI Interconnect IP也配置成相同的模式1输入4输出,并将fmch_axi_iic重新连接到M03_AXI接口。
将中断前的concat改为6输入。连接tpg、mix、frmbuf_wr的中断输出。

最终vmda相关的连线如下图
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第14张图片
zynq_us相关的连线如下图
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第15张图片
总体连线如下图
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第16张图片
auto assign address将所有ip的寄存器偏移进行配置,然后将不用的OCM、QSPI、PCIE存储空间unmap掉
17.png
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第17张图片
validate design验证设计
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第18张图片

将不会用到的audio相关rtl代码以及audio相关的xdc约束删除。

直接点击Generate Bitstream
在有cache的基础上大概编译了半个小时。
资源使用较demo来说dsp、bram和lut占用增长了许多
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第19张图片

Export Hardware, Launch SDK完成这一阶段的设计

2 SDK 工程修改

对于HDMI RX通道来说,完全被修改了,需要重新设计驱动代码。
对于HDMI TX通道来说,我保留了TPG模块,所以可以将代码部分修改即可进行HDMI输出测试,这样也挺好的。
生成了一个新的exdes_wrapper_hw_platform_1,将原来的*_0删除。
因为驱动要变,所以重新生成一个Passthrough_A53例程,并进行修改,重新生成前需要将原有程序代码和bsp删除。勾选删除源文件。
使用默认配置生成一个新的bsp:zcu102_hdmi_frame_bsp
导入hdmi Passthrough_A53例程。
可以看到例子中有错误,这是因为我们删掉了audio相关的东西以及一些其他内容导致的。我们现在开始剪裁这个代码,使他满足我们现在的fpga逻辑。
结果发现简单的修改就能正常编译了。。

XPAR_V_TPG_SS_0_AXI_GPIO_DEVICE_ID
换成XPAR_V_DMA_SS_AXI_GPIO_DEVICE_ID

XPAR_V_TPG_SS_0_V_TPG_DEVICE_ID换成
XPAR_V_DMA_SS_V_TPG_DEVICE_ID

先不管mix和frmbuf_wr的驱动,直接用保留的TPG测试HDMI TX的输出。
烧录fpga,烧录ps,屏幕一闪,看来能用啊。
3. ZCU102 HDMI Demo工程修改【PCIE视频传输】_第20张图片
因为不能TPG的输入时MIX,所以没有passthrough功能了,手动配置,按”c”选择输出colorbar,显示器能够显示,表明HDMI TX通道是能够正常用的,只要编写mix的驱动就可以了。
而且从前面图中的log可以看到

RX stream is up

所以说明输入通道也是ok的,只要编写frmbuf_wr的驱动就可以了。
把两个驱动编写完毕,再用三重缓冲的方式将显存调度起来,应该就能够间接实现passthrough功能了。

虽然这样能用,但是还有audio相关的代码没有删除或是屏蔽,最好处理一下。。

下面的log测试了输出不同分辨率和tpg产生的pattern图形,都是正常的。

Starting colorbar
RX stream is up
TX stream is up
--------
Pass-Through :
        Color Format:     RGB
        Color Depth:      8
        Pixels Per Clock: 2
        Mode:             Progressive
        Frame Rate:       60Hz
        Resolution:       1920x1080@60Hz
        Pixel Clock:      148500000
--------
Starting colorbar
TX stream is down
TX stream is up
--------
Colorbar :
        Color Format:     RGB
        Color Depth:      8
        Pixels Per Clock: 2
        Mode:             Progressive
        Frame Rate:       60Hz
        Resolution:       1920x1080@60Hz
        Pixel Clock:      148500000
--------

---------------------------
---   RESOLUTION MENU   ---
---------------------------
 1 -  720 x 480p
 2 -  720 x 576p
 3 - 1280 x 720p
 4 - 1680 x 720p
 5 - 1920 x 1080p
 6 - 2560 x 1080p
 7 - 3840 x 2160p
 8 - 4096 x 2160p
 9 - 1920 x 1080i
10 -  640 x 480p (VGA / DMT0659)
11 -  800 x 600p (SVGA / DMT0860)
12 - 1024 x 768p (XGA / DMT1060)
13 - 1280 x 768p (WXGA / CVT1260E)
14 - 1366 x 768p (WXGA+ / DMT1360)
15 - 1280 x 1024p (SXGA / DMT1260G)
16 - 1680 x 1050p (WSXGA+ / CVT1660D)
17 - 1600 x 1200p (UXGA / DMT1660)
18 - 1920 x 1200p (WUXGA / CVT1960D)
19 -  720 x 480i (NTSC)
20 -  720 x 576i (PAL)
21 - 3840 x 2160p (SB) (Custom)
99 - Exit
Starting colorbar> 4
TX stream is down
TX stream is up
--------
Colorbar :
        Color Format:     RGB
        Color Depth:      8
        Pixels Per Clock: 2
        Mode:             Progressive
        Frame Rate:       60Hz
        Resolution:       1680x720@60Hz
        Pixel Clock:      99000000
--------
Starting colorbar> 3
TX stream is down
TX stream is up
--------
Colorbar :
        Color Format:     RGB
        Color Depth:      8
        Pixels Per Clock: 2
        Mode:             Progressive
        Frame Rate:       60Hz
        Resolution:       1280x720@60Hz
        Pixel Clock:      74250000
--------
Starting colorbar> 5
TX stream is down
TX stream is up
--------
Colorbar :
        Color Format:     RGB
        Color Depth:      8
        Pixels Per Clock: 2
        Mode:             Progressive
        Frame Rate:       60Hz
        Resolution:       1920x1080@60Hz
        Pixel Clock:      148500000
--------
Returning to main menu.

----------------------
---   VIDEO MENU   ---
----------------------
  1 - Color bars
  2 - Solid red
  3 - Solid green
  4 - Solid blue
  5 - Solid black
  6 - Solid white
  7 - Horizontal ramp
  8 - Vertical ramp
  9 - Rainbow color
 10 - Checker board
 11 - Cross hatch
 12 - Noise
 13 - Black (Video Mask)
 14 - White (Video Mask)
 15 - Red (Video Mask)
 16 - Green (Video Mask)
 17 - Blue (Video Mask)
 18 - Noise (Video Mask)
 99 - Exit

其中的9 - Rainbow color看起来效果不错,以前都是拿的ZedBoard的VGA接口进行测试的,RGB三色的深度太小,显示出来都是离散的色块,现在拿RGB24来显示,果然比较平滑了。

修改颜色格式为RGB、YUV444、YUV422也都是能用的,但是切换的时候应该是有个bug,会同时将颜色深度变为12,显示器就会不正常显示了。

感觉这个demo的测试程序还是写的非常好的,比较稳定,以后要是还会用到的话,可以拿来借鉴。

3 程序梳理

下面对demo程序进行梳理,将他的程序流程整理出来。
这里就不画框图了,文字整理。

  1. 杂项
    • 声明相关变量、结构体指针
    • 打印启动信息,包含了elf编译的时间
    • 标志位初始化
  2. 初始化基本功能
    • 初始化ps端的iic0、iic1
    • 使用iic1配置U34 iic扩展芯片(0x74),将iic1总线switch到(第5个通道,0x10)U20时钟芯片(驱动里面是Si5324,实际是Si5328)
    • 使用iic1-ch5,配置Si5328时钟芯片(0x69)
      1. 3,0x15。在校准时关闭时钟输出。
      2. 4,0x92。自动选择时钟并可逆,history delay default。
      3. 6,0x0f。输出信号电平CKOUT1、CKOUT2:Low swing LVDS
      4. 10,0x08。CKOUT2 disabled,CKOUT1 enabled。
      5. 11,0x42。CKIN2 disabled,CKIN1 enabled。
      6. 19,0x23。设置快速时钟
      7. 137,0x01。使能快速锁定。
      8. 输入设置为晶体输入114285000Hz,输出为156250000Hz。
        • 使用软件计算出分频倍频数值。
        • 0,0x54。使用xtal输入,使能free running。
        • 配置分频倍频系数到芯片。
      9. 仔细看了一下,这个芯片实际在ZCU102里面是驱动SFP的,不知道干嘛还要这个,直接删掉??。。。
    • 使用pl端的axi_iic,配置Si5324时钟芯片(0x68)
      1. 配置与Si5328前半部分相同。
      2. 输入时钟选择CKIN1,输出选择CKOUT1。
      3. 完成配置。
    • 没有使用HDCP功能,很大一部分代码被注释了
    • 初始化中断功能Gic
  3. 初始化HDMI相关功能
    • 默认配置初始化HDMI_TX_SS模块
    • 将HDMI_TX_SS模块的中断服务程序绑定到对应Gic的中断号上
    • 使能Gic中HDMI_TX_SS的中断
    • 配置HDMI_TX_SS模块的回调函数接口
      1. XV_HDMITXSS_HANDLER_CONNECT-> TxConnectCallback
      2. XV_HDMITXSS_HANDLER_TOGGLE-> TxToggleCallback
      3. XV_HDMITXSS_HANDLER_VS-> TxVsCallback
      4. XV_HDMITXSS_HANDLER_STREAM_UP-> TxStreamUpCallback
      5. XV_HDMITXSS_HANDLER_STREAM_DOWN-> TxStreamDownCallback
      6. 各个回调函数功能如其名称
    • 配置HDMI_RX_SS模块中的EDID信息
    • 默认配置初始化HDMI_RX_SS模块
    • 将HDMI_RX_SS模块的中断服务程序绑定到对应Gic的中断号上
    • 使能Gic中HDMI_RX_SS的中断
    • 配置HDMI_RX_SS模块的回调函数接口
      1. XV_HDMIRXSS_HANDLER_CONNECT-> RxConnectCallback
      2. XV_HDMIRXSS_HANDLER_AUX-> RxAuxCallback
      3. XV_HDMIRXSS_HANDLER_AUD-> RxAudCallback
      4. XV_HDMIRXSS_HANDLER_LNKSTA-> RxLnkStaCallback
      5. XV_HDMIRXSS_HANDLER_STREAM_DOWN-> RxStreamDownCallback
      6. XV_HDMIRXSS_HANDLER_STREAM_INIT-> RxStreamInitCallback
      7. XV_HDMIRXSS_HANDLER_STREAM_UP-> RxStreamUpCallback
      8. 各个回调函数功能如其名称
    • 默认配置初始化Video_PHY模块
    • 将Video_PHY模块的中断服务程序绑定到对应Gic的中断号上
    • 使能Gic中Video_PHY的中断
    • 配置Video_PHY模块的回调函数接口
      1. XVPHY_HDMI_HANDLER_TXINIT-> VphyHdmiTxInitCallback
      2. XVPHY_HDMI_HANDLER_TXREADY-> VphyHdmiTxReadyCallback
      3. XVPHY_HDMI_HANDLER_RXINIT-> VphyHdmiRxInitCallback
      4. XVPHY_HDMI_HANDLER_RXREADY-> VphyHdmiRxReadyCallback
      5. VphyErrorCallback
      6. 各个回调函数功能如其名称
  4. 初始化其他图像相关模块
    • 默认配置,初始化AXI_GPIO模块
    • 复位TPG模块
    • 默认配置,初始化TPG模块
  5. 设置程序异常回调函数,并使能异常检测
  6. 初始化HDMI Menu软件模块
  7. 初始化Video_PHY和HDMI_TX_SS模块,使能Colorbar、1080p、RGB8输出配置,HDMI RX不接的情况下会输入,加入RX接了输入信号,会快速的触发中断,改为passthrough模式?
  8. 进入程序的主循环
    • 根据是否接入了RX信号,来进行模式配置
      1. RX电缆连接、RX数据流建立成功会将StartTxAfterRxFlag置为TRUE,触发运行StartTxAfterRx
        • 清除StartTxAfterRxFlag为FALSE
        • 关闭Video_PHY的TX TMDS的OBUFTDS差分时钟
        • 开启HDMI TX的流,设置像素速率、颜色深度、颜色格式、scrambler?、时钟速率、写log
        • 打开Video_PHY的RX TMDS的OBUFTDS差分时钟输出
        • 判断HDMI TX和HDMI RX是否绑定在了一个GT收发器上
          1. 不在一个GT上,需要对收发参考时钟进行频率一致的设置
          2. 在一个GT上
            • 复位Si5324
            • 重新初始化Si5324
        • 复位TPG模块
        • 重新根据HDMI分辨率配置TPG模块
        • 如果HDMI TX和HDMI RX绑定在一个GT上,打开Video_PHY的TX TMDS的OBUFTDS差分时钟
      2. TX电缆连接、RX连接会将TxRestartColorbar置为TRUE
        • 清除TxRestartColorbar为FALSE
        • 运行EnableColorBar
    • TX的流建立成功后,会将IsStreamUp置为TRUE
      1. 清除IsStreamUp为FASLE
      2. 通过AXI_IIC根据Video_PHY的信息配置DP159芯片
      3. 打开Video_PHY的TX TMDS的OBUFTDS差分时钟
    • 运行HDMI Menu程序模块,响应指令并作出动作
    • 根据VphyErrorFlag标志来进行错误处理,Video_PHY的错误回调函数会将VphyErrorCallback置为TRUE
      asd

4 总结

把HDMI的Demo的大概结构已经理清楚了,下一次拿以前写好的mix和frmbuf_wr的驱动添加到工程,把初始化以及相关的中断程序写好来进行带帧缓冲的透传功能。当然,可以将一些图像处理算法加进来,这样系统的功能就比较强大了~
帧同步的方法看起来是需要在XV_HDMITXSS_HANDLER_VS中断里面去做,就先这样吧。

你可能感兴趣的:(Xilinx,FPGA)