16.1 - VDMA视频转发实验之TPG

文章目录

  • [1 实验任务](#1 实验任务)
  • [2 系统框图](#2 系统框图)
  • [3 硬件设计](#3 硬件设计)
    • [3.1 IP核配置](#3.1 IP核配置)
    • [3.2 注意事项](#3.2 注意事项)
  • [4 软件设计](#4 软件设计)
    • [4.1 注意事项](#4.1 注意事项)
    • [4.2 工程源码](#4.2 工程源码)
      • [4.2.1 main.c文件](#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核配置

  1. 配置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)保持默认值,采用动态同步锁相模式,写通道为主,读通道为从
  2. 配置TGP IP核
    • (1)全部保持默认即可

3.2 注意事项

为各个接口自动连线:必须手动指定主从接口和互联模块的时钟

  1. 为VDMA的M_AXI_S2MM接口连线:从接口是PS的S_AXI_HP0接口
  2. 为TPG的s_axi_CTRL接口连线:主接口是PS的M_AXI_GP0接口,注意
    • (1)TPG只有一个时钟接口ap_clk,该时钟是AXI4-Stream data interface和AXI4-Lite control interface共用,所以时钟源选择的是Clocking Wizard输出的clk_out1时钟,即视频时钟,使输入视频和输出视频同步
  3. 将TPG和VDMA连接起来,为VDMA的s_axis_s2mm_aclk连线,自动识别为Clocking Wizard输出的clk_out1时钟,即视频时钟

4 软件设计

4.1 注意事项

  1. TPG IP核生成一个背景为纯白,叠加一个黑色移动小方块的视频
  2. 当VDMA写通道停止时
    • (1)VDMA写通道暂停接收视频数据,TPG暂停产生视频数据
    • (2)VDMA读通道依然在发送数据
      • 1)显示器上小方块停止移动
      • 2)说明VDMA读通道在重复发送同一帧视频数据,该帧视频数据是VDMA写通道在停止前写入的最后一帧
      • 3)符合动态同步锁相模式的工作机制,即读通道(Dynamic Genlock Slave)会操作写通道(Dynamic Genlock Master)上一个周期操作的帧
  3. 当VDMA写通道重启时
    • (1)TPG恢复产生视频数据
    • (2)显示器上小方块继续从停止的位置开始移动

4.2 工程源码

4.2.1 main.c文件

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;
}

/*****************************************************************************/

/*****************************************************************************/
相关推荐
eewj1 天前
STM32中FCLK时钟信号的作用
stm32·单片机·嵌入式硬件
淘晶驰AK1 天前
ESP32和STM32哪个更容易学?
stm32·单片机·嵌入式硬件
__万波__1 天前
STM32L475实现精度更好的delay函数
stm32·单片机·嵌入式硬件
QK_001 天前
STM32-热敏传感器以及光敏传感器
stm32·单片机·嵌入式硬件
代码游侠1 天前
复习——ARM Cortex-A 裸机开发深度解析
arm开发·笔记·嵌入式硬件·学习·架构
清风6666661 天前
基于单片机的燃气热水器智能控制系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
youcans_1 天前
【动手学STM32G4】(2)STM32G431之外部中断—按键控制
stm32·单片机·嵌入式硬件·外部中断
Smart-佀1 天前
FPGA入门:CAN总线原理与Verilog代码详解
单片机·嵌入式硬件·物联网·算法·fpga开发
老李的森林1 天前
嵌入式开发--无刷电机FOC控制--用定时器事件驱动ADC采样
stm32·单片机·嵌入式硬件·foc·无刷电机
一路往蓝-Anbo1 天前
【第42期】调试进阶(一):IDE中的Register与Memory窗口
c语言·开发语言·ide·stm32·单片机·嵌入式硬件