赞
踩
《Zynq-PS-SDK(13) 之 VDMA+VTC+AXI4S-VideoOut 视频通路软件配置》将硬件做好后,导出到 SDK,我们进行代码的编写,代码主要分为两部分:
1、SCCB 的 I2C 对 OV5640 进行配置;
2、配置 VDMA + VTC + Dynamic Clock;
先 reset,完成 SCCB 的配置,然后进行 IP 核的配置,main 函数如下所示:
- /************************************************************************/
- /* */
- /* display_demo.c -- ALINX AX7010 HDMI Display demonstration */
- /* */
- /************************************************************************/
-
- /* ------------------------------------------------------------ */
- /* Include File Definitions */
- /* ------------------------------------------------------------ */
-
- #include "display_demo.h"
- #include "display_ctrl/display_ctrl.h"
- #include <stdio.h>
- #include "math.h"
- #include <ctype.h>
- #include <stdlib.h>
- #include "xil_types.h"
- #include "xil_cache.h"
- #include "xparameters.h"
- #include "xiicps.h"
- #include "vdma.h"
- #include "i2c/PS_i2c.h"
- #include "xgpio.h"
- #include "sleep.h"
- #include "ov5640.h"
- #include "steph_vdma.h"
- /*
- * XPAR redefines
- */
- #define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR
- #define VGA_VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID
- #define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID
- #define VID_VTC_IRPT_ID XPS_FPGA3_INT_ID
- #define VID_GPIO_IRPT_ID XPS_FPGA4_INT_ID
- #define SCU_TIMER_ID XPAR_SCUTIMER_DEVICE_ID
- #define UART_BASEADDR XPAR_PS7_UART_1_BASEADDR
-
-
- /* ------------------------------------------------------------ */
- /* Global Variables */
- /* ------------------------------------------------------------ */
-
- /*
- * Display Driver structs
- */
- DisplayCtrl dispCtrl;
- XAxiVdma vdma;
- XIicPs ps_i2c0;
- XGpio cmos_rstn;
- /*
- * Framebuffers for video data
- */
- u8 frameBuf[DISPLAY_NUM_FRAMES][DEMO_MAX_FRAME] __attribute__ ((aligned(64)));
- u8 *pFrames[DISPLAY_NUM_FRAMES]; //array of pointers to the frame buffers
-
- /* ------------------------------------------------------------ */
- /* Procedure Definitions */
- /* ------------------------------------------------------------ */
-
-
-
- int main(void)
- {
-
- int Status;
- XAxiVdma_Config *vdmaConfig;
- int i;
-
- /*
- * Initialize an array of pointers to the 3 frame buffers
- */
- for (i = 0; i < DISPLAY_NUM_FRAMES; i++)
- {
- pFrames[i] = frameBuf[i];
- memset(pFrames[i], 0, DEMO_MAX_FRAME);
- Xil_DCacheFlushRange((INTPTR) pFrames[i], DEMO_MAX_FRAME) ;
- }
-
- i2c_init(&ps_i2c0, XPAR_XIICPS_0_DEVICE_ID,40000);
-
- XGpio_Initialize(&cmos_rstn, XPAR_CMOS_RST_DEVICE_ID); //initialize GPIO IP
- XGpio_SetDataDirection(&cmos_rstn, 1, 0x0); //set GPIO as output
- XGpio_DiscreteWrite(&cmos_rstn, 1, 0x1);
- usleep(500000);
- XGpio_DiscreteWrite(&cmos_rstn, 1, 0x0); //set GPIO output value to 0
-
- usleep(500000);
- XGpio_DiscreteWrite(&cmos_rstn, 1, 0x1);
- usleep(500000);
-
- /*
- * Initialize Sensor
- */
- sensor_init(&ps_i2c0);
- /*
- * Initialize VDMA driver
- */
-
- // Reset StephenZhou's IP
- Xil_Out32(XPAR_STEPH_OV5640_0_S00_AXI_BASEADDR, 0x00000000);
- usleep(500000);
- Xil_Out32(XPAR_STEPH_OV5640_0_S00_AXI_BASEADDR, 0x00000001);
-
- vdmaConfig = XAxiVdma_LookupConfig(VGA_VDMA_ID);
- if (!vdmaConfig)
- {
- xil_printf("No video DMA found for ID %d\r\n", VGA_VDMA_ID);
-
- }
- Status = XAxiVdma_CfgInitialize(&vdma, vdmaConfig, vdmaConfig->BaseAddress);
- if (Status != XST_SUCCESS)
- {
- xil_printf("VDMA Configuration Initialization failed %d\r\n", Status);
-
- }
-
- /*
- * Initialize the Display controller and start it
- */
- Status = DisplayInitialize(&dispCtrl, &vdma, DISP_VTC_ID, DYNCLK_BASEADDR,pFrames, DEMO_STRIDE);
- if (Status != XST_SUCCESS)
- {
- xil_printf("Display Ctrl initialization failed during demo initialization%d\r\n", Status);
-
- }
- Status = DisplayStart(&dispCtrl);
- if (Status != XST_SUCCESS)
- {
- xil_printf("Couldn't start display during demo initialization%d\r\n", Status);
-
- }
- /* Clear frame buffer */
- memset(dispCtrl.framePtr[dispCtrl.curFrame], 0, 1920 * 1080 * 3);
- /* Start Sensor Vdma */
- // vdma_write_init(XPAR_AXIVDMA_1_DEVICE_ID,1280 * 3,720,1280 * 3,(unsigned int)dispCtrl.framePtr[dispCtrl.curFrame]);
-
- Steph_VDMAInit(&vdma, VGA_VDMA_ID, 1280, 720, DEMO_STRIDE, (unsigned int) pFrames[0]);
- while(1);
-
- return 0;
- }
-
-

VDMA 的配置,配置了读写通道:
- /******************** Include files **********************************/
- #include "xaxivdma.h"
- #include "xparameters.h"
- #include "xil_exception.h"
-
- #define STEPH_VDMA_DBG 1
-
- typedef struct steph_vdma_desc {
-
- /** The XAxiVdma driver instance data. */
- XAxiVdma* InstancePtr;
- /** The Read channel configure. */
- XAxiVdma_DmaSetup ReadCfg;
- /** The Write channel configure. */
- XAxiVdma_DmaSetup WriteCfg;
- /* Horizontal size of frame */
- unsigned int hsize;
- /* Stride horizontal size of frame */
- unsigned int stride;
- /* Vertical size of frame */
- unsigned int vsize;
- /* FrameBuffer address from where read and write will be done by VDMA */
- unsigned int fb_addr;
-
- } steph_vdma_desc_t;
-
- steph_vdma_desc_t steph_vdma;
-
- static int _Steph_VDMA_ConfigWriteChannel(steph_vdma_desc_t *steph_vdma)
- {
- int Status = XST_SUCCESS;
- u32 Addr;
-
- steph_vdma->WriteCfg.VertSizeInput = steph_vdma->vsize;
- steph_vdma->WriteCfg.HoriSizeInput = steph_vdma->hsize;
- steph_vdma->WriteCfg.Stride = steph_vdma->stride;
-
- steph_vdma->WriteCfg.FrameDelay = 0;
- // Circular mode
- steph_vdma->WriteCfg.EnableCircularBuf = 1;
- // GenLock enable
- steph_vdma->WriteCfg.EnableSync = 1;
- steph_vdma->WriteCfg.PointNum = 0;
- steph_vdma->WriteCfg.EnableFrameCounter = 0;
- /* We are not doing parking */
- steph_vdma->WriteCfg.FixedFrameStoreAddr= 0;
- steph_vdma->WriteCfg.GenLockRepeat = 0;
-
- Status = XAxiVdma_DmaConfig(steph_vdma->InstancePtr, XAXIVDMA_WRITE, &steph_vdma->WriteCfg);
- if (Status != XST_SUCCESS) {
- xil_printf("[ERROR] : Write channel config failed %d\r\n", Status);
- return Status;
- }
-
- // Configure the framebuffer
- Addr = steph_vdma->fb_addr;
- for(int Index = 0; Index < steph_vdma->InstancePtr->MaxNumFrames; Index++)
- {
- steph_vdma->WriteCfg.FrameStoreStartAddr[Index] = Addr;
- Addr += (steph_vdma->hsize * steph_vdma->vsize);
- }
-
- // Set the framebuffer addresses for transfer in the DMA engine
- Status = XAxiVdma_DmaSetBufferAddr(steph_vdma->InstancePtr, XAXIVDMA_WRITE,
- steph_vdma->WriteCfg.FrameStoreStartAddr);
-
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Write channel set buffer address failed %d\r\n", Status);
- return Status;
- }
-
- return Status;
- }
-
- static int _Steph_VDMA_ConfigReadChannel(steph_vdma_desc_t *steph_vdma)
- {
- int Status = XST_SUCCESS;
- u32 Addr;
-
- steph_vdma->ReadCfg.VertSizeInput = steph_vdma->vsize;
- steph_vdma->ReadCfg.HoriSizeInput = steph_vdma->hsize;
- steph_vdma->ReadCfg.Stride = steph_vdma->stride;
-
- steph_vdma->ReadCfg.FrameDelay = 0;
- // Circular mode
- steph_vdma->ReadCfg.EnableCircularBuf = 1;
- // GenLock enable
- steph_vdma->ReadCfg.EnableSync = 1;
- steph_vdma->ReadCfg.PointNum = 0;
- steph_vdma->ReadCfg.EnableFrameCounter = 0;
- /* We are not doing parking */
- steph_vdma->ReadCfg.FixedFrameStoreAddr= 0;
- steph_vdma->ReadCfg.GenLockRepeat = 0;
-
- Status = XAxiVdma_DmaConfig(steph_vdma->InstancePtr, XAXIVDMA_READ, &steph_vdma->ReadCfg);
- if (Status != XST_SUCCESS) {
- xil_printf("[ERROR] : Read channel config failed %d\r\n", Status);
- return Status;
- }
-
- // Configure the framebuffer
- Addr = steph_vdma->fb_addr;
- for(int Index = 0; Index < steph_vdma->InstancePtr->MaxNumFrames; Index++)
- {
- steph_vdma->ReadCfg.FrameStoreStartAddr[Index] = Addr;
- Addr += (steph_vdma->hsize * steph_vdma->vsize);
- }
-
- // Set the framebuffer addresses for transfer in the DMA engine
- Status = XAxiVdma_DmaSetBufferAddr(steph_vdma->InstancePtr, XAXIVDMA_READ,
- steph_vdma->ReadCfg.FrameStoreStartAddr);
-
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Read channel set buffer address failed %d\r\n", Status);
- return Status;
- }
-
- return Status;
- }
-
- static int _Steph_VDMA_StartWriteChannel(steph_vdma_desc_t *steph_vdma)
- {
- int Status = XST_SUCCESS;
-
- Status = XAxiVdma_DmaStart(steph_vdma->InstancePtr, XAXIVDMA_WRITE);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Start Write transfer failed %d\r\n", Status);
- }
-
- return Status;
- }
-
- static int _Steph_VDMA_StartReadChannel(steph_vdma_desc_t *steph_vdma)
- {
- int Status = XST_SUCCESS;
-
- Status = XAxiVdma_DmaStart(steph_vdma->InstancePtr, XAXIVDMA_READ);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Start Read transfer failed %d\r\n", Status);
- }
-
- return Status;
- }
-
- int Steph_VDMAInit(XAxiVdma *_InstancePtr, int device_id, int hsize, int vsize, int stride, int fb_addr)
- {
- int Status = XST_SUCCESS;
- XAxiVdma_Config *Config;
-
- Config = XAxiVdma_LookupConfig(device_id);
- if (!Config)
- {
- xil_printf("[ERROR] : No video DMA found for ID %d\r\n",device_id);
- return XST_FAILURE;
- }
-
- /* Initialize DMA engine */
- Status = XAxiVdma_CfgInitialize(_InstancePtr, Config, Config->BaseAddress);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Configuration Initialization failed %d\r\n",Status);
- return Status;
- }
-
- steph_vdma.InstancePtr = _InstancePtr;
- steph_vdma.hsize = hsize * (Config->Mm2SStreamWidth>>3);
- steph_vdma.stride = stride;
- steph_vdma.vsize = vsize;
- steph_vdma.fb_addr = fb_addr;
-
- #ifdef STEPH_VDMA_DBG
- xil_printf("hsize = %d\r\n",hsize);
- xil_printf("stride = %d\r\n",steph_vdma.stride);
- xil_printf("vsize = %d\r\n",vsize);
- xil_printf("fb_addr = 0x%08X\r\n",fb_addr);
- #endif
-
- // Configure the write channel
- Status = _Steph_VDMA_ConfigWriteChannel(&steph_vdma);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Write channel setup failed %d\r\n", Status);
- return Status;
- }
-
- // Configure the read channel
- Status = _Steph_VDMA_ConfigReadChannel(&steph_vdma);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Read channel setup failed %d\r\n", Status);
- return Status;
- }
-
- // Start the write channel
- Status = _Steph_VDMA_StartWriteChannel(&steph_vdma);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Start Write channel failed %d\r\n", Status);
- return Status;
- }
-
- // Configure the read channel
- Status = _Steph_VDMA_StartReadChannel(&steph_vdma);
- if (Status != XST_SUCCESS)
- {
- xil_printf("[ERROR] : Start Read channel failed %d\r\n", Status);
- return Status;
- }
-
- xil_printf("StephenZhou VDMA OK...\r\n");
-
- return Status;
- }

3 块 framebuffer 轮流使用,开启 GenLock;
更多寄存器的配置详细,参考 pg020;主要是配置一些宽,高,framebuffer 地址,GenLock 同步方式等;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。