16 - VDMA之视频转发实验
文章目录
- 1 实验任务
- 2 系统框图
- 3 硬件设计
- 3.1 IP核配置
- 3.2 注意事项
- 4 软件设计
- 4.1 注意事项
- 4.2 工程源码
- 4.2.1 main.c文件
1 实验任务
基于14.1,使用Xilinx TPG(Test Pattern Generator) IP提供视频源,将视频数据通过VDMA写入PS侧内存,然后再通过VDMA将视频数据从PS侧内存读出来,最后通过HDMI接口发送出去,即实现视频转发的功能。
2 系统框图
基于14.1,添加TPG IP核作为视频源,连接到VDMA的写通道,如下图所示:
3 硬件设计
3.1 IP核配置
- 配置VDMA IP核
- (1)Basic页面
- 1)Frame Buffers:选择默认值3,即缓存3帧图像数据
- 2)Enable Write Channel:勾选,使能写通道
- 3)Write Burst Size:选择256,最大化传输效率
- 4)Line Buffer Depth:选择2048,图像分辨率为1920x1080,能够缓存一行像素数据
- (2)Advanced页面
- 1)保持默认值,采用动态同步锁相模式,写通道为主,读通道为从
- 1)保持默认值,采用动态同步锁相模式,写通道为主,读通道为从
- (1)Basic页面
- 配置TGP IP核
- (1)全部保持默认即可
- (1)全部保持默认即可
3.2 注意事项
为各个接口自动连线:必须手动指定主从接口和互联模块的时钟
- 为VDMA的M_AXI_S2MM接口连线:从接口是PS的S_AXI_HP0接口
- 为TPG的s_axi_CTRL接口连线:主接口是PS的M_AXI_GP0接口,注意
- (1)TPG只有一个时钟接口ap_clk,该时钟是AXI4-Stream data interface和AXI4-Lite control interface共用,所以时钟源选择的是Clocking Wizard输出的clk_out1时钟,即视频时钟,是输入视频和输出视频同步
- (1)TPG只有一个时钟接口ap_clk,该时钟是AXI4-Stream data interface和AXI4-Lite control interface共用,所以时钟源选择的是Clocking Wizard输出的clk_out1时钟,即视频时钟,是输入视频和输出视频同步
- 将TPG和VDMA连接起来,为VDMA的s_axis_s2mm_aclk连线,自动识别为Clocking Wizard输出的clk_out1时钟,即视频时钟
4 软件设计
4.1 注意事项
- TPG IP核生成一个背景为纯白,叠加一个黑色移动小方块的视频
- 当VDMA写通道停止接收数据时
- (1)TPG视频接口的输入信号m_axis_video_TREADY被VDMA写通道拉低,TPG暂停产生视频数据
- (2)显示器并未黑屏,此时显示器上小方块停止移动,说明VDMA读通道依然在工作,只不过在反复从同一个内存地址读取视频数据,该帧视频数据是VDMA写通道在停止前写入的最后一帧;这符合动态同步锁相模式的工作机制,即读通道(Dynamic Genlock Slave)会操作写通道(Dynamic Genlock Master)上一个周期操作的帧
- 当VDMA写通道重启接收数据时
- (1)TPG继续产生视频数据
- (2)显示器上小方块继续从之前停止的位置开始移动
4.2 工程源码
4.2.1 main.c文件
/********************************************************************/#include "vdma/vdma_api.h"#include "xparameters.h"
#include "stdio.h"
#include "sleep.h"
#include "xv_tpg.h"/********************************************************************/#define TPG_DEVICE_ID XPAR_V_TPG_0_DEVICE_ID
#define VDMA_DEVICE_ID XPAR_AXIVDMA_0_DEVICE_ID
#define MEMORY_BASEADDR XPAR_PS7_DDR_0_S_AXI_BASEADDR#define IMAGE_WIDTH 1920
#define IMAGE_HEIGHT 1080/********************************************************************//********************************************************************/XV_tpg TpgInst;
XAxiVdma VdmaInst;int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);/********************************************************************/int main()
{//int Status;u32 BackGndPatternId;u32 ForeGndPatternId;u32 BoxSize;u32 BoxColorRed;u32 BoxColorGreen;u32 BoxColorBlue;u32 MotionSpeed;//printf("Vdma Video Forward Test.\n");//Status = XV_tpg_Initialize(&TpgInst, TPG_DEVICE_ID);if (Status == XST_FAILURE) {printf("Error : video test pattern generator initialization failed.\n");return XST_FAILURE;}//BackGndPatternId = 0x8;ForeGndPatternId = 0x1;BoxSize = 0x20;BoxColorRed = 0x00;BoxColorGreen = 0x00;BoxColorBlue = 0x00;MotionSpeed = 0x2;XV_tpg_Set_width(&TpgInst, IMAGE_WIDTH);XV_tpg_Set_height(&TpgInst, IMAGE_HEIGHT);XV_tpg_Set_bckgndId(&TpgInst, BackGndPatternId);XV_tpg_Set_boxSize(&TpgInst, BoxSize);XV_tpg_Set_boxColorR(&TpgInst, BoxColorRed);XV_tpg_Set_boxColorG(&TpgInst, BoxColorGreen);XV_tpg_Set_boxColorB(&TpgInst, BoxColorBlue);XV_tpg_Set_motionSpeed(&TpgInst, MotionSpeed);XV_tpg_Set_ovrlayId(&TpgInst, ForeGndPatternId);XV_tpg_Start(&TpgInst);XV_tpg_EnableAutoRestart(&TpgInst);// 启动VDMA读写操作Status = run_vdma_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0, BOTH);if (Status == XST_FAILURE) {printf("Error : run vdma frame buffer failed.\n");return XST_FAILURE;}//while (1) {//sleep(10);printf("Stop vdma channel.\n");
// XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_WRITE);//sleep(5);printf("Start vdma channel.\n");
// XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_WRITE);}//return XST_SUCCESS;
}/*****************************************************************************//*****************************************************************************/