From f3e699e477509a2e573cc64f730138cc0621e2d8 Mon Sep 17 00:00:00 2001 From: Anurag Kumar Vulisha Date: Tue, 28 Jul 2015 12:55:33 +0530 Subject: [PATCH] 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 Reviewed-by: Kedareswara rao Appana --- .../drivers/axivdma/data/dependencies.props | 3 + .../drivers/axivdma/examples/vdma.c | 288 +++++++++++ .../drivers/axivdma/examples/vdma_api.c | 458 ++++++++++++++++++ .../examples/xaxivdma_example_readme.txt | 34 ++ .../drivers/axivdma/src/xaxivdma.h | 2 +- 5 files changed, 784 insertions(+), 1 deletion(-) create mode 100644 XilinxProcessorIPLib/drivers/axivdma/data/dependencies.props create mode 100644 XilinxProcessorIPLib/drivers/axivdma/examples/vdma.c create mode 100644 XilinxProcessorIPLib/drivers/axivdma/examples/vdma_api.c create mode 100644 XilinxProcessorIPLib/drivers/axivdma/examples/xaxivdma_example_readme.txt diff --git a/XilinxProcessorIPLib/drivers/axivdma/data/dependencies.props b/XilinxProcessorIPLib/drivers/axivdma/data/dependencies.props new file mode 100644 index 00000000..a8b47873 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/axivdma/data/dependencies.props @@ -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 diff --git a/XilinxProcessorIPLib/drivers/axivdma/examples/vdma.c b/XilinxProcessorIPLib/drivers/axivdma/examples/vdma.c new file mode 100644 index 00000000..cc5ab5d2 --- /dev/null +++ b/XilinxProcessorIPLib/drivers/axivdma/examples/vdma.c @@ -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); + +} diff --git a/XilinxProcessorIPLib/drivers/axivdma/examples/vdma_api.c b/XilinxProcessorIPLib/drivers/axivdma/examples/vdma_api.c new file mode 100644 index 00000000..1d9bc3ae --- /dev/null +++ b/XilinxProcessorIPLib/drivers/axivdma/examples/vdma_api.c @@ -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;jInstancePtr->MaxNumFrames;j++) { + for(pixels=0;pixelsReadCfg.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;ihsize * 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; +} diff --git a/XilinxProcessorIPLib/drivers/axivdma/examples/xaxivdma_example_readme.txt b/XilinxProcessorIPLib/drivers/axivdma/examples/xaxivdma_example_readme.txt new file mode 100644 index 00000000..7f67816d --- /dev/null +++ b/XilinxProcessorIPLib/drivers/axivdma/examples/xaxivdma_example_readme.txt @@ -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. diff --git a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h index bb0413bb..3faa1e4b 100644 --- a/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h +++ b/XilinxProcessorIPLib/drivers/axivdma/src/xaxivdma.h @@ -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. * * ******************************************************************************/