以下步骤是最简单的VDMA控制初始化操作。
Ø 写VDMACR寄存器,将VDMACR.RS设为1,启动VDMA通道。
Ø 设定有效的帧缓存起始地址。
Ø 设定帧延迟(仅针对Genlock从模式)以及跨度到FRMDLY_STRIDE寄存器。
Ø 设定水平方向字节数到HSIZE寄存器。
Ø 设定竖直方向行数到VSIZE寄存器。启动通道的数据传输。
在VDMA运行过程中,可以动态的进行显示参数配置,但是需要注意的是,想要使参数生效,必须在设置的最后一步,对VSIZE寄存器进行写操作。
初始化方法一:
把helloworld.c里的代码修改如下:
#include <stdio.h>
#include "platform.h"
#include "xil_io.h"
int main()
{
init_platform();
xil_printf("----------The test is start......----------\n\r");
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x4); //reset S2MM VDMA Control Register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x8); //genlock
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x08000000);//S2MM Start Addresses
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+4, 0x0A000000);
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+8, 0x09000000);
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 1920*3);//S2MM Horizontal Size
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 0x01002000);//S2MM Frame Delay and Stride
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x3);//S2MM VDMA Control Register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 1080);//S2MM Vertical Size start an S2MM transfer
//AXI VDMA1
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x4); //reset MM2S VDMA Control Register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x8); //gen-lock
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C, 0x08000000); //MM2S Start Addresses
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C+4, 0x0A000000);
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C+8, 0x09000000);
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x54, 1920*3);//MM2S HSIZE Register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x58, 0x01002000);//S2MM FRMDELAY_STRIDE Register 1920*3=5760 对齐之后为8192=0x2000
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x03);//MM2S VDMA Control Register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x50, 1080);//MM2S_VSIZE 启动传输
cleanup_platform();
return 0;
}
本课程提供了二种方式启动VDMA,第一种是通过库函数版本,第二种是通过寄存器版本。寄存器版本主要是验证我们对VDMA的寄存器掌握情况。库函数具备更强的功能,和可维护性。
表6-6-1
#include "sys_intr.h" #include "xaxivdma.h" #include "xaxivdma_i.h" #define VTC_BASEADDR XPAR_MIZ702_VTG_VGA_0_BASEADDR #define DDR_BASEADDR 0x00000000 //#define UART_BASEADDR 0xe0001000 #define VDMA_BASEADDR XPAR_AXI_VDMA_0_BASEADDR #define H_STRIDE 640 #define H_ACTIVE 640 #define V_ACTIVE 480 #define pi 3.14159265358 #define COUNTS_PER_SECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ)/64 #define VIDEO_LENGTH (H_STRIDE*V_ACTIVE) #define VIDEO_BASEADDR0 DDR_BASEADDR + 0x2000000 #define VIDEO_BASEADDR1 DDR_BASEADDR + 0x3000000 #define VIDEO_BASEADDR2 DDR_BASEADDR + 0x4000000 u32 *BufferPtr[3]; unsigned int srcBuffer = (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000); int run_triple_frame_buffer(XAxiVdma* InstancePtr, int DeviceId, int hsize, int vsize, int buf_base_addr, int number_frame_count, int enable_frm_cnt_intr); int main(void) { u32 Status; Miz702_EMIO_init(); ov7725_init_rgb(); XAxiVdma InstancePtr; xil_printf("Starting the first VDMA \n\r"); Status = run_triple_frame_buffer(&InstancePtr, 0, 640, 480, srcBuffer, 2, 0); if (Status != XST_SUCCESS) { xil_printf("Transfer of frames failed with error = %d\r\n",Status); return XST_FAILURE; } else { xil_printf("Transfer of frames started \r\n"); } print("TEST PASS\r\n"); //VDMA configurateAXI VDMA0 /****************往DDR写数据设置**********************/ /*Xil_Out32((VDMA_BASEADDR + 0x030), 0x00000003);// enable circular mode Xil_Out32((VDMA_BASEADDR + 0x0AC), VIDEO_BASEADDR0); // start address Xil_Out32((VDMA_BASEADDR + 0x0B0), VIDEO_BASEADDR1); // start address Xil_Out32((VDMA_BASEADDR + 0x0B4), VIDEO_BASEADDR2); // start address Xil_Out32((VDMA_BASEADDR + 0x0A8), (H_STRIDE*4)); // h offset (640 * 4) bytes Xil_Out32((VDMA_BASEADDR + 0x0A4), (H_ACTIVE*4)); // h size (640 * 4) bytes Xil_Out32((VDMA_BASEADDR + 0x0A0), V_ACTIVE);*/ // v size (480) /*****************从DDR读数据设置**********************/ /*Xil_Out32((VDMA_BASEADDR + 0x000), 0x00000003); // enable circular mode Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0); // start address Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR1); // start address Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR2); // start address Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*4)); // h offset (640 * 4) bytes Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*4)); // h size (640 * 4) bytes Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE); // v size (480) */ while (1) ; return XST_SUCCESS; } |