vdma: Add example for vdma triple buffer api

This patch adds vdma  application to demonstrate how to use the VDMA triple buffer API.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Reviewed-by: Kedareswara rao Appana <appanad@xilinx.com>
This commit is contained in:
Anurag Kumar Vulisha 2015-07-28 12:55:33 +05:30 committed by Nava kishore Manne
parent 1728d93515
commit f3e699e477
5 changed files with 784 additions and 1 deletions

View file

@ -0,0 +1,3 @@
vdma.c=vdma_api.c
xaxivdma_example_intr.c=xaxivdma_example_intr.c
xaxivdma_example_selftest.c=xaxivdma_example_selftest.c

View file

@ -0,0 +1,288 @@
/******************************************************************************
*
* Copyright (C) 2014 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file vdma.c
*
* This file comprises sample application to usage of VDMA APi's in vdma_api.c.
* .
*
* ***************************************************************************/
/*** Include file ***/
#include "xparameters.h"
#include "xstatus.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_assert.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
/*** Global Variables ***/
unsigned int srcBuffer = (XPAR_MIG7SERIES_0_BASEADDR + 0x1000000);
/* Instance of the Interrupt Controller */
static XIntc Intc;
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);
static int SetupIntrSystem(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId,
u16 WriteIntrId);
/*****************************************************************************/
/*
* Main function
*
* This is main entry point to demonstrate this example.
*
* @return None
*
******************************************************************************/
int main(){
int Status;
XAxiVdma InstancePtr;
XAxiVdma InstancePtr_1;
xil_printf("\n--- Entering main() --- \r\n");
xil_printf("Starting the first VDMA \n\r");
/* Calling the API to configure and start VDMA without frame counter interrupt */
Status = run_triple_frame_buffer(&InstancePtr, 0, 1920, 1080,
srcBuffer, 100, 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");
}
xil_printf("Starting the second VDMA \r\n");
/* Calling the API to configure and start second VDMA with frame counter interrupt
* Please note source buffer pointer is being offset a bit */
Status = run_triple_frame_buffer(&InstancePtr_1, 1, 1920, 1080,
srcBuffer + 0x1000000, 100, 1);
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");
}
/* Enabling the interrupt for second VDMA */
SetupIntrSystem(&InstancePtr_1, XPAR_INTC_0_AXIVDMA_1_MM2S_INTROUT_VEC_ID,
XPAR_INTC_0_AXIVDMA_1_S2MM_INTROUT_VEC_ID);
/* Infinite while loop to let it run */
while(1);
}
/*****************************************************************************/
/*
* Call back function for read channel
*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void ReadCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Read Call back function is called\r\n");
}
/*****************************************************************************/
/*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void ReadErrorCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Read Call back Error function is called\r\n");
}
/*****************************************************************************/
/*The user can put his code that should get executed when this
* call back happens.
*
*
* This callback only clears the interrupts and updates the transfer status.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void WriteCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Write Call back function is called\r\n");
}
/*****************************************************************************/
/*
* The user can put his code that should get executed when this
* call back happens.
*
* @param CallbackRef is the call back reference pointer
* @param Mask is the interrupt mask passed in from the driver
*
* @return None
*
******************************************************************************/
static void WriteErrorCallBack(void *CallbackRef, u32 Mask)
{
/* User can add his code in this call back function */
xil_printf("Write Call back Error function is called \r\n");
}
/*****************************************************************************/
/*
*
* This function setups the interrupt system so interrupts can occur for the
* DMA. This function assumes INTC component exists in the hardware system.
*
* @param AxiDmaPtr is a pointer to the instance of the DMA engine
* @param ReadIntrId is the read channel Interrupt ID.
* @param WriteIntrId is the write channel Interrupt ID.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int SetupIntrSystem(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId,
u16 WriteIntrId)
{
int Status;
XIntc *IntcInstancePtr =&Intc;
/* Initialize the interrupt controller and connect the ISRs */
Status = XIntc_Initialize(IntcInstancePtr, XPAR_INTC_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf( "Failed init intc\r\n");
return XST_FAILURE;
}
Status = XIntc_Connect(IntcInstancePtr, ReadIntrId,
(XInterruptHandler)XAxiVdma_ReadIntrHandler, AxiVdmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed read channel connect intc %d\r\n", Status);
return XST_FAILURE;
}
Status = XIntc_Connect(IntcInstancePtr, WriteIntrId,
(XInterruptHandler)XAxiVdma_WriteIntrHandler, AxiVdmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed write channel connect intc %d\r\n", Status);
return XST_FAILURE;
}
/* Start the interrupt controller */
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
xil_printf( "Failed to start intc\r\n");
return XST_FAILURE;
}
/* Enable interrupts from the hardware */
XIntc_Enable(IntcInstancePtr, ReadIntrId);
XIntc_Enable(IntcInstancePtr, WriteIntrId);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
/* Register call-back functions
*/
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL, ReadCallBack,
(void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR,
ReadErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_READ);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_GENERAL,
WriteCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
XAxiVdma_SetCallBack(AxiVdmaPtr, XAXIVDMA_HANDLER_ERROR,
WriteErrorCallBack, (void *)AxiVdmaPtr, XAXIVDMA_WRITE);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts
*
* @param ReadIntrId is interrupt ID associated w/ DMA read channel
* @param WriteIntrId is interrupt ID associated w/ DMA write channel
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void DisableIntrSystem(u16 ReadIntrId, u16 WriteIntrId)
{
/* Disconnect the interrupts for the DMA TX and RX channels */
XIntc_Disconnect(&Intc, ReadIntrId);
XIntc_Disconnect(&Intc, WriteIntrId);
}

View file

@ -0,0 +1,458 @@
/******************************************************************************
*
* Copyright (C) 2014 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file vdma_api.c
*
* This file has high level API to configure and start the VDMA.The file assumes that:
* The design has VDMA with both MM2S and S2MM path enable.
* The API's has tested with hardware that has tow VDMA and MM2S to S2MM are back
* to back connected for each VDMA.
*
* ***************************************************************************/
#define DEBUG_MODE 0
/******************** Include files **********************************/
#include "xaxivdma.h"
#include "xparameters.h"
#include "xil_exception.h"
/******************** Data structure Declarations *****************************/
typedef struct vdma_handle
{
/* The device ID of the VDMA */
unsigned int device_id;
/* The state variable to keep track if the initialization is done*/
unsigned int init_done;
/** The XAxiVdma driver instance data. */
XAxiVdma* InstancePtr;
/* The XAxiVdma_DmaSetup structure contains all the necessary information to
* start a frame write or read. */
XAxiVdma_DmaSetup ReadCfg;
XAxiVdma_DmaSetup WriteCfg;
/* Horizontal size of frame */
unsigned int hsize;
/* Vertical size of frame */
unsigned int vsize;
/* Buffer address from where read and write will be done by VDMA */
unsigned int buffer_address;
/* Flag to tell VDMA to interrupt on frame completion*/
unsigned int enable_frm_cnt_intr;
/* The counter to tell VDMA on how many frames the interrupt should happen*/
unsigned int number_of_frame_count;
}vdma_handle;
/******************** Constant Definitions **********************************/
/*
* Device related constants. These need to defined as per the HW system.
*/
vdma_handle vdma_context[XPAR_XAXIVDMA_NUM_INSTANCES];
static unsigned int context_init=0;
/******************* Function Prototypes ************************************/
static int ReadSetup(vdma_handle *vdma_context);
static int WriteSetup(vdma_handle *vdma_context);
static int StartTransfer(XAxiVdma *InstancePtr);
/*****************************************************************************/
/**
*
* run_triple_frame_buffer API
*
* This API is the interface between application and other API. When application will call
* this API with right argument, This API will call rest of the API to configure the read
* and write path of VDMA,based on ID. After that it will start both the read and write path
* of VDMA
*
* @param InstancePtr is the handle to XAxiVdma data structure.
* @param DeviceId is the device ID of current VDMA
* @param hsize is the horizontal size of the frame. It will be in Pixels.
* The actual size of frame will be calculated by multiplying this
* with tdata width.
* @param vsize is the Vertical size of the frame.
* @param buf_base_addr is the buffer address where frames will be written
* and read by VDMA.
* @param number_frame_count specifies after how many frames the interrupt
* should come.
* @param enable_frm_cnt_intr is for enabling frame count interrupt
* when set to 1.
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if example fails.
*
******************************************************************************/
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 Status,i;
XAxiVdma_Config *Config;
XAxiVdma_FrameCounter FrameCfgPtr;
/* This is one time initialization of state machine context.
* In first call it will be done for all VDMA instances in the system.
*/
if(context_init==0) {
for(i=0; i < XPAR_XAXIVDMA_NUM_INSTANCES; i++) {
vdma_context[i].InstancePtr = NULL;
vdma_context[i].device_id = -1;
vdma_context[i].hsize = 0;
vdma_context[i].vsize = 0;
vdma_context[i].init_done = 0;
vdma_context[i].buffer_address = 0;
vdma_context[i].enable_frm_cnt_intr = 0;
vdma_context[i].number_of_frame_count = 0;
}
context_init = 1;
}
/* The below initialization will happen for each VDMA. The API argument
* will be stored in internal data structure
*/
/* The information of the XAxiVdma_Config comes from hardware build.
* The user IP should pass this information to the AXI DMA core.
*/
Config = XAxiVdma_LookupConfig(DeviceId);
if (!Config) {
xil_printf("No video DMA found for ID %d\r\n",DeviceId );
return XST_FAILURE;
}
if(vdma_context[DeviceId].init_done ==0) {
vdma_context[DeviceId].InstancePtr = InstancePtr;
/* Initialize DMA engine */
Status = XAxiVdma_CfgInitialize(vdma_context[DeviceId].InstancePtr,
Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
xil_printf("Configuration Initialization failed %d\r\n",
Status);
return XST_FAILURE;
}
vdma_context[DeviceId].init_done = 1;
}
vdma_context[DeviceId].device_id = DeviceId;
vdma_context[DeviceId].vsize = vsize;
vdma_context[DeviceId].buffer_address = buf_base_addr;
vdma_context[DeviceId].enable_frm_cnt_intr = enable_frm_cnt_intr;
vdma_context[DeviceId].number_of_frame_count = number_frame_count;
vdma_context[DeviceId].hsize = hsize * (Config->Mm2SStreamWidth>>3);
/* Setup the write channel */
Status = WriteSetup(&vdma_context[DeviceId]);
if (Status != XST_SUCCESS) {
xil_printf("Write channel setup failed %d\r\n", Status);
if(Status == XST_VDMA_MISMATCH_ERROR)
xil_printf("DMA Mismatch Error\r\n");
return XST_FAILURE;
}
/* Setup the read channel */
Status = ReadSetup(&vdma_context[DeviceId]);
if (Status != XST_SUCCESS) {
xil_printf("Read channel setup failed %d\r\n", Status);
if(Status == XST_VDMA_MISMATCH_ERROR)
xil_printf("DMA Mismatch Error\r\n");
return XST_FAILURE;
}
/* The frame counter interrupt is enabled, setting VDMA for same */
if(vdma_context[DeviceId].enable_frm_cnt_intr) {
FrameCfgPtr.ReadDelayTimerCount = 1;
FrameCfgPtr.ReadFrameCount = number_frame_count;
FrameCfgPtr.WriteDelayTimerCount = 1;
FrameCfgPtr.WriteFrameCount = number_frame_count;
XAxiVdma_SetFrameCounter(vdma_context[DeviceId].InstancePtr,&FrameCfgPtr);
/* Enable DMA read and write channel interrupts. The configuration for interrupt
* controller will be done by application */
XAxiVdma_IntrEnable(vdma_context[DeviceId].InstancePtr,
XAXIVDMA_IXR_ERROR_MASK |
XAXIVDMA_IXR_FRMCNT_MASK,XAXIVDMA_WRITE);
XAxiVdma_IntrEnable(vdma_context[DeviceId].InstancePtr,
XAXIVDMA_IXR_ERROR_MASK |
XAXIVDMA_IXR_FRMCNT_MASK,XAXIVDMA_READ);
} else {
/* Enable DMA read and write channel interrupts. The configuration for interrupt
* controller will be done by application */
XAxiVdma_IntrEnable(vdma_context[DeviceId].InstancePtr,
XAXIVDMA_IXR_ERROR_MASK,XAXIVDMA_WRITE);
XAxiVdma_IntrEnable(vdma_context[DeviceId].InstancePtr,
XAXIVDMA_IXR_ERROR_MASK ,XAXIVDMA_READ);
}
/* Start the DMA engine to transfer */
Status = StartTransfer(vdma_context[DeviceId].InstancePtr);
if (Status != XST_SUCCESS) {
if(Status == XST_VDMA_MISMATCH_ERROR)
xil_printf("DMA Mismatch Error\r\n");
return XST_FAILURE;
}
#if DEBUG_MODE
xil_printf("Code is in Debug mode, Make sure that buffer addresses are at valid memory \r\n");
xil_printf("In triple mode, there has to be six consecutive buffers for Debug mode \r\n");
{
u32 pixels,j,Addr = vdma_context[DeviceId].buffer_address;
u8 *dst,*src;
u32 total_pixel = vdma_context[DeviceId].stride * vdma_context[DeviceId].vsize;
src = (unsigned char *)Addr;
dst = (unsigned char *)Addr + (total_pixel * vdma_context->InstancePtr->MaxNumFrames);
for(j=0;j<vdma_context->InstancePtr->MaxNumFrames;j++) {
for(pixels=0;pixels<total_pixel;pixels++) {
if(src[pixels] != dst[pixels]) {
xil_printf("VDMA transfer failed: SRC=0x%x, DST=0x%x\r\n",
src[pixels],dst[pixels]);
exit(-1);
}
}
src = src + total_pixel;
dst = dst + total_pixel;
}
}
xil_printf("VDMA transfer is happening and checked for 3 frames \r\n");
#endif
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function sets up the read channel
*
* @param vdma_context is the context pointer to the VDMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int ReadSetup(vdma_handle *vdma_context)
{
int Index;
u32 Addr;
int Status;
vdma_context->ReadCfg.VertSizeInput = vdma_context->vsize;
vdma_context->ReadCfg.HoriSizeInput = vdma_context->hsize;
vdma_context->ReadCfg.Stride = vdma_context->hsize;
vdma_context->ReadCfg.FrameDelay = 0; /* This example does not test frame delay */
vdma_context->ReadCfg.EnableCircularBuf = 1;
vdma_context->ReadCfg.EnableSync = 1; /* Gen-Lock */
vdma_context->ReadCfg.PointNum = 0;
vdma_context->ReadCfg.EnableFrameCounter = 0; /* Endless transfers */
vdma_context->ReadCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */
/* Configure the VDMA is per fixed configuration, This configuration is being used by majority
* of customer. Expert users can play around with this if they have different configurations */
Status = XAxiVdma_DmaConfig(vdma_context->InstancePtr, XAXIVDMA_READ, &vdma_context->ReadCfg);
if (Status != XST_SUCCESS) {
xil_printf("Read channel config failed %d\r\n", Status);
return XST_FAILURE;
}
/* Initialize buffer addresses
*
* These addresses are physical addresses
*/
Addr = vdma_context->buffer_address;
for(Index = 0; Index < vdma_context->InstancePtr->MaxNumFrames; Index++) {
vdma_context->ReadCfg.FrameStoreStartAddr[Index] = Addr;
/* Initializing the buffer in case of Debug mode */
#if DEBUG_MODE
{
u32 i;
u8 *src;
u32 total_pixel = vdma_context->stride * vdma_context->vsize;
src = (unsigned char *)Addr;
xil_printf("Read Buffer %d address: 0x%x \r\n",Index,Addr);
for(i=0;i<total_pixel;i++)
{
src[i] = i & 0xFF;
}
}
#endif
Addr += vdma_context->hsize * vdma_context->vsize;
}
/* Set the buffer addresses for transfer in the DMA engine
* The buffer addresses are physical addresses
*/
Status = XAxiVdma_DmaSetBufferAddr(vdma_context->InstancePtr, XAXIVDMA_READ,
vdma_context->ReadCfg.FrameStoreStartAddr);
if (Status != XST_SUCCESS) {
xil_printf(
"Read channel set buffer address failed %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function sets up the write channel
*
* @param dma_context is the context pointer to the VDMA engine..
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int WriteSetup(vdma_handle *vdma_context)
{
int Index;
u32 Addr;
int Status;
vdma_context->WriteCfg.VertSizeInput = vdma_context->vsize;
vdma_context->WriteCfg.HoriSizeInput = vdma_context->hsize;
vdma_context->WriteCfg.Stride = vdma_context->hsize;
vdma_context->WriteCfg.FrameDelay = 0; /* This example does not test frame delay */
vdma_context->WriteCfg.EnableCircularBuf = 1;
vdma_context->WriteCfg.EnableSync = 1; /* Gen-Lock */
vdma_context->WriteCfg.PointNum = 0;
vdma_context->WriteCfg.EnableFrameCounter = 0; /* Endless transfers */
vdma_context->WriteCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */
/* Configure the VDMA is per fixed configuration, This configuration
* is being used by majority of customers. Expert users can play around
* with this if they have different configurations
*/
Status = XAxiVdma_DmaConfig(vdma_context->InstancePtr, XAXIVDMA_WRITE, &vdma_context->WriteCfg);
if (Status != XST_SUCCESS) {
xil_printf(
"Write channel config failed %d\r\n", Status);
return Status;
}
/* Initialize buffer addresses
*
* Use physical addresses
*/
Addr = vdma_context->buffer_address;
/* If Debug mode is enabled write frame is shifted 3 Frames
* store ahead to compare read and write frames
*/
#if DEBUG_MODE
Addr = Addr + vdma_context->InstancePtr->MaxNumFrames * \
(vdma_context->stride * vdma_context->vsize);
#endif
for(Index = 0; Index < vdma_context->InstancePtr->MaxNumFrames; Index++) {
vdma_context->WriteCfg.FrameStoreStartAddr[Index] = Addr;
#if DEBUG_MODE
xil_printf("Write Buffer %d address: 0x%x \r\n",Index,Addr);
#endif
Addr += (vdma_context->hsize * vdma_context->vsize);
}
/* Set the buffer addresses for transfer in the DMA engine */
Status = XAxiVdma_DmaSetBufferAddr(vdma_context->InstancePtr,
XAXIVDMA_WRITE,
vdma_context->WriteCfg.FrameStoreStartAddr);
if (Status != XST_SUCCESS) {
xil_printf("Write channel set buffer address failed %d\r\n",
Status);
return XST_FAILURE;
}
/* Clear data buffer
*/
#if DEBUG_MODE
memset((void *)vdma_context->buffer_address, 0,
vdma_context->ReadCfg.Stride * vdma_context->ReadCfg.VertSizeInput * vdma_context->InstancePtr->MaxNumFrames);
#endif
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function starts the DMA transfers. Since the DMA engine is operating
* in circular buffer mode, video frames will be transferred continuously.
*
* @param InstancePtr points to the DMA engine instance
*
* @return
* - XST_SUCCESS if both read and write start successfully
* - XST_FAILURE if one or both directions cannot be started
*
* @note None.
*
******************************************************************************/
static int StartTransfer(XAxiVdma *InstancePtr)
{
int Status;
/* Start the write channel of VDMA */
Status = XAxiVdma_DmaStart(InstancePtr, XAXIVDMA_WRITE);
if (Status != XST_SUCCESS) {
xil_printf("Start Write transfer failed %d\r\n", Status);
return XST_FAILURE;
}
/* Start the Read channel of VDMA */
Status = XAxiVdma_DmaStart(InstancePtr, XAXIVDMA_READ);
if (Status != XST_SUCCESS) {
xil_printf("Start read transfer failed %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,34 @@
vdma_readme.txt
---------------
The examples in this directory are provided to give the user some idea of how the VDMA
and its driver are intended to be used.
Examples:
1. AXI VDMA SELFTEST EXAMPLE:
This example does basic reset of the VDMA core.
FILES:
* xaxivdma_example_selftest.c - This file does the basic reset of vdma core.
2.AXI VDMA INTERRUPT EXAMPLE:
This example demonstrates how to use the AXI Video DMA with other video IPs to do video frame transfers.
This example does not work by itself. It needs two other Video IPs, one for writing video frames to the
memory and one for reading video frames from the memory.
FILES:
* xaxivdma_example_intr.c - This file runs interrupt example for data transfer.
3.AXI VDMA TRIPLE BUFFER EXAMPLE:
This VDMA example demonstrates how to use the VDMA triple buffer API.
FILES:
* vdma_api.c - This file has high level API's to configure and start the VDMA transfer.
* vdma.c - This file comprises sample application to the usage of VDMA API's in vdma_api.c.
NOTE:
* These examples assumes that the design has VDMA with both MM2S and S2MM path enable.

View file

@ -282,7 +282,7 @@
* test example to include it on peripheral test's(CR#823144).
* 5.1 adk 29/01/15 Added the sefltest api (XAxiVdma_Selftest) to the driver source files
* (xaxivdma_selftest.c) and called this from the selftest example
*
* 6.0 vak 27/07/15 Added example for demonstarting triple buffer api.
* </pre>
*
******************************************************************************/