/****************************************************************************** * * Copyright (C) 2012 - 2014 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 THE * XILINX CONSORTIUM 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 xaxivdma_example_intr.c * * 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. * * To see the debug print, you need a Uart16550 or uartlite in your system, * and please set "-DDEBUG" in your compiler options. You need to rebuild your * software executable. * * @note * The values of DDR_BASE_ADDR and DDR_HIGH_ADDR should be as per the HW system. * *
 * MODIFICATION HISTORY:
 *
 * Ver   Who  Date     Changes
 * ----- ---- -------- -------------------------------------------------------
 * 1.00a jz   07/26/10 First release
 * 1.01a jz   09/26/10 Updated callback function signature
 * 2.00a jz   12/10/10 Added support for direct register access mode, v3 core
 * 2.01a rvp  01/22/11 Renamed the example file to be consistent
 * 		       Added support to the example to use SCU GIC interrupt
 *		       controller for ARM, some functions in this example have
 *		       changed.
 *       rkv  03/28/11 Updated to support for frame store register.
 * 3.00a srt  08/26/11 Added support for Flush on Frame Sync Feature.
 * 4.00a srt  03/06/12 Modified interrupt support for Zynq.
 * 4.02a srt  09/25/12 Fixed CR 677704 
 *		       Description - Arguments misused in function 
 *                     XAxiVdma_IntrEnable(). 
 * 4.03a srt  03/01/13 Updated DDR base address for IPI designs (CR 703656).
 * 
* * *************************************************************************** */ #include "xaxivdma.h" #include "xparameters.h" #include "xil_exception.h" #ifdef XPAR_INTC_0_DEVICE_ID #include "xintc.h" #else #include "xscugic.h" #endif #ifndef __MICROBLAZE__ #include "xpseudo_asm_gcc.h" #include "xreg_cortexa9.h" #endif #if defined(XPAR_UARTNS550_0_BASEADDR) #include "xuartns550_l.h" /* to use uartns550 */ #endif /******************** Constant Definitions **********************************/ /* * Device related constants. These need to defined as per the HW system. */ #define DMA_DEVICE_ID XPAR_AXIVDMA_0_DEVICE_ID #ifdef XPAR_INTC_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define WRITE_INTR_ID XPAR_INTC_0_AXIVDMA_0_S2MM_INTROUT_VEC_ID #define READ_INTR_ID XPAR_INTC_0_AXIVDMA_0_MM2S_INTROUT_VEC_ID #else #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID #define WRITE_INTR_ID XPAR_FABRIC_AXIVDMA_0_S2MM_INTROUT_VEC_ID #define READ_INTR_ID XPAR_FABRIC_AXIVDMA_0_MM2S_INTROUT_VEC_ID #endif #ifdef XPAR_V6DDR_0_S_AXI_BASEADDR #define DDR_BASE_ADDR XPAR_V6DDR_0_S_AXI_BASEADDR #define DDR_HIGH_ADDR XPAR_V6DDR_0_S_AXI_HIGHADDR #elif XPAR_S6DDR_0_S0_AXI_BASEADDR #define DDR_BASE_ADDR XPAR_S6DDR_0_S0_AXI_BASEADDR #define DDR_HIGH_ADDR XPAR_S6DDR_0_S0_AXI_HIGHADDR #elif XPAR_AXI_7SDDR_0_S_AXI_BASEADDR #define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR #define DDR_HIGH_ADDR XPAR_AXI_7SDDR_0_S_AXI_HIGHADDR #elif XPAR_MIG7SERIES_0_BASEADDR #define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR #define DDR_HIGH_ADDR XPAR_MIG7SERIES_0_HIGHADDR #else #warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \ DEFAULT SET TO 0x01000000 #define DDR_BASE_ADDR 0x01000000 #define DDR_HIGH_ADDR 0x0F000000 #endif /* Memory space for the frame buffers * * This example only needs one set of frame buffers, because one video IP is * to write to the frame buffers, and the other video IP is to read from the * frame buffers. * * For 16 frames of 1080p, it needs 0x07E90000 memory for frame buffers */ #define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x01000000) #define MEM_HIGH_ADDR DDR_HIGH_ADDR #define MEM_SPACE (MEM_HIGH_ADDR - MEM_BASE_ADDR) /* Read channel and write channel start from the same place * * One video IP write to the memory region, the other video IP read from it */ #define READ_ADDRESS_BASE MEM_BASE_ADDR #define WRITE_ADDRESS_BASE MEM_BASE_ADDR /* Frame size related constants */ #define FRAME_HORIZONTAL_LEN 0x1E00 /* 1920 pixels, each pixel 4 bytes */ #define FRAME_VERTICAL_LEN 0x438 /* 1080 pixels */ /* Subframe to be transferred by Video DMA * *|<----------------- FRAME_HORIZONTAL_LEN ---------------------->| * -------------------------------------------------------------------- *| | ^ *| | | *| |<-SUBFRAME_HORIZONTAL_SIZE ->| | FRAME_ *| ----------------------------------- | VERTICAL_ *| |/////////////////////////////| ^ | LEN *| |/////////////////////////////| | | | *| |/////////////////////////////| | | | *| |/////////////////////////////| SUBFRAME_ | | *| |/////////////////////////////| VERTICAL_ | | *| |/////////////////////////////| SIZE | | *| |/////////////////////////////| | | | *| |/////////////////////////////| v | | *| ---------------------------------- | | *| | v *-------------------------------------------------------------------- * * Note that SUBFRAME_HORIZONTAL_SIZE and SUBFRAME_VERTICAL_SIZE must ensure * to be inside the frame. */ #define SUBFRAME_START_OFFSET (FRAME_HORIZONTAL_LEN * 5 + 32) #define SUBFRAME_HORIZONTAL_SIZE 100 #define SUBFRAME_VERTICAL_SIZE 100 /* Number of frames to work on, this is to set the frame count threshold * * We multiply 15 to the num stores is to increase the intervals between * interrupts. If you are using fsync, then it is not necessary. */ #define NUMBER_OF_READ_FRAMES 8 #define NUMBER_OF_WRITE_FRAMES 8 /* Number of frames to transfer * * This is used to monitor the progress of the test, test purpose only */ #define NUM_TEST_FRAME_SETS 10 /* Delay timer counter * * WARNING: If you are using fsync, please increase the delay counter value * to be 255. Because with fsync, the inter-frame delay is long. If you do not * care about inactivity of the hardware, set this counter to be 0, which * disables delay interrupt. */ #define DELAY_TIMER_COUNTER 10 /* * Device instance definitions */ XAxiVdma AxiVdma; #ifdef XPAR_INTC_0_DEVICE_ID static XIntc Intc; /* Instance of the Interrupt Controller */ #else static XScuGic Intc; /* Instance of the Interrupt Controller */ #endif /* Data address * * Read and write sub-frame use the same settings */ static u32 ReadFrameAddr; static u32 WriteFrameAddr; static u32 BlockStartOffset; static u32 BlockHoriz; static u32 BlockVert; /* DMA channel setup */ static XAxiVdma_DmaSetup ReadCfg; static XAxiVdma_DmaSetup WriteCfg; /* Transfer statics */ static int ReadDone; static int ReadError; static int WriteDone; static int WriteError; /******************* Function Prototypes ************************************/ static int ReadSetup(XAxiVdma *InstancePtr); static int WriteSetup(XAxiVdma * InstancePtr); static int StartTransfer(XAxiVdma *InstancePtr); static int SetupIntrSystem(XAxiVdma *AxiVdmaPtr, u16 ReadIntrId, u16 WriteIntrId); static void DisableIntrSystem(u16 ReadIntrId, u16 WriteIntrId); /* Interrupt call back functions */ static void ReadCallBack(void *CallbackRef, u32 Mask); static void ReadErrorCallBack(void *CallbackRef, u32 Mask); static void WriteCallBack(void *CallbackRef, u32 Mask); static void WriteErrorCallBack(void *CallbackRef, u32 Mask); #if defined(XPAR_UARTNS550_0_BASEADDR) /*****************************************************************************/ /* * * Uart16550 setup routine, need to set baudrate to 9600 and data bits to 8 * * ******************************************************************************/ static void Uart550_Setup(void) { /* Set the baudrate to be predictable */ XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600); XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR, XUN_LCR_8_DATA_BITS); } #endif /*****************************************************************************/ /** * * Main function * * This function is the main entry point of the example on DMA core. It sets up * DMA engine to be ready to receive and send frames, and start the transfers. * It waits for the transfer of the specified number of frame sets, and check * for transfer errors. * * @return * - XST_SUCCESS if example finishes successfully * - XST_FAILURE if example fails. * * @note None. * ******************************************************************************/ int main(void) { int Status; XAxiVdma_Config *Config; XAxiVdma_FrameCounter FrameCfg; #if defined(XPAR_UARTNS550_0_BASEADDR) Uart550_Setup(); #endif WriteDone = 0; ReadDone = 0; WriteError = 0; ReadError = 0; ReadFrameAddr = READ_ADDRESS_BASE; WriteFrameAddr = WRITE_ADDRESS_BASE; BlockStartOffset = SUBFRAME_START_OFFSET; BlockHoriz = SUBFRAME_HORIZONTAL_SIZE; BlockVert = SUBFRAME_VERTICAL_SIZE; xil_printf("\r\n--- Entering main() --- \r\n"); /* 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(DMA_DEVICE_ID); if (!Config) { xil_printf( "No video DMA found for ID %d\r\n", DMA_DEVICE_ID); return XST_FAILURE; } /* Initialize DMA engine */ Status = XAxiVdma_CfgInitialize(&AxiVdma, Config, Config->BaseAddress); if (Status != XST_SUCCESS) { xil_printf( "Configuration Initialization failed %d\r\n", Status); return XST_FAILURE; } Status = XAxiVdma_SetFrmStore(&AxiVdma, NUMBER_OF_READ_FRAMES, XAXIVDMA_READ); if (Status != XST_SUCCESS) { xil_printf( "Setting Frame Store Number Failed in Read Channel" " %d\r\n", Status); return XST_FAILURE; } Status = XAxiVdma_SetFrmStore(&AxiVdma, NUMBER_OF_WRITE_FRAMES, XAXIVDMA_WRITE); if (Status != XST_SUCCESS) { xil_printf( "Setting Frame Store Number Failed in Write Channel" " %d\r\n", Status); return XST_FAILURE; } /* Setup frame counter and delay counter for both channels * * This is to monitor the progress of the test only * * WARNING: In free-run mode, interrupts may overwhelm the system. * In that case, it is better to disable interrupts. */ FrameCfg.ReadFrameCount = NUMBER_OF_READ_FRAMES; FrameCfg.WriteFrameCount = NUMBER_OF_WRITE_FRAMES; FrameCfg.ReadDelayTimerCount = DELAY_TIMER_COUNTER; FrameCfg.WriteDelayTimerCount = DELAY_TIMER_COUNTER; Status = XAxiVdma_SetFrameCounter(&AxiVdma, &FrameCfg); if (Status != XST_SUCCESS) { xil_printf( "Set frame counter failed %d\r\n", Status); if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } /* * Setup your video IP that writes to the memory */ /* Setup the write channel */ Status = WriteSetup(&AxiVdma); 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 your video IP that reads from the memory */ /* Setup the read channel */ Status = ReadSetup(&AxiVdma); 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; } Status = SetupIntrSystem(&AxiVdma, READ_INTR_ID, WRITE_INTR_ID); if (Status != XST_SUCCESS) { xil_printf( "Setup interrupt system failed %d\r\n", Status); return XST_FAILURE; } /* Register callback functions */ XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_GENERAL, ReadCallBack, (void *)&AxiVdma, XAXIVDMA_READ); XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_ERROR, ReadErrorCallBack, (void *)&AxiVdma, XAXIVDMA_READ); XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_GENERAL, WriteCallBack, (void *)&AxiVdma, XAXIVDMA_WRITE); XAxiVdma_SetCallBack(&AxiVdma, XAXIVDMA_HANDLER_ERROR, WriteErrorCallBack, (void *)&AxiVdma, XAXIVDMA_WRITE); /* Enable your video IP interrupts if needed */ /* Start the DMA engine to transfer */ Status = StartTransfer(&AxiVdma); if (Status != XST_SUCCESS) { if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } /* Enable DMA read and write channel interrupts * * If interrupts overwhelms the system, please do not enable interrupt */ XAxiVdma_IntrEnable(&AxiVdma, XAXIVDMA_IXR_ALL_MASK, XAXIVDMA_WRITE); XAxiVdma_IntrEnable(&AxiVdma, XAXIVDMA_IXR_ALL_MASK, XAXIVDMA_READ); /* Every set of frame buffer finish causes a completion interrupt */ while ((WriteDone < NUM_TEST_FRAME_SETS) && !ReadError && (ReadDone < NUM_TEST_FRAME_SETS) && !WriteError) { /* NOP */ } if (ReadError || WriteError) { xil_printf("Test has transfer error %d/%d\r\n", ReadError, WriteError); Status = XST_FAILURE; } else { xil_printf("Test passed\r\n"); } xil_printf("--- Exiting main() --- \r\n"); DisableIntrSystem(READ_INTR_ID, WRITE_INTR_ID); if (Status != XST_SUCCESS) { if(Status == XST_VDMA_MISMATCH_ERROR) xil_printf("DMA Mismatch Error\r\n"); return XST_FAILURE; } return XST_SUCCESS; } /*****************************************************************************/ /** * * This function sets up the read channel * * @param InstancePtr is the instance pointer to the DMA engine. * * @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise. * * @note None. * ******************************************************************************/ static int ReadSetup(XAxiVdma *InstancePtr) { int Index; u32 Addr; int Status; ReadCfg.VertSizeInput = SUBFRAME_VERTICAL_SIZE; ReadCfg.HoriSizeInput = SUBFRAME_HORIZONTAL_SIZE; ReadCfg.Stride = FRAME_HORIZONTAL_LEN; ReadCfg.FrameDelay = 0; /* This example does not test frame delay */ ReadCfg.EnableCircularBuf = 1; ReadCfg.EnableSync = 0; /* No Gen-Lock */ ReadCfg.PointNum = 0; /* No Gen-Lock */ ReadCfg.EnableFrameCounter = 0; /* Endless transfers */ ReadCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */ Status = XAxiVdma_DmaConfig(InstancePtr, XAXIVDMA_READ, &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 = READ_ADDRESS_BASE + BlockStartOffset; for(Index = 0; Index < NUMBER_OF_READ_FRAMES; Index++) { ReadCfg.FrameStoreStartAddr[Index] = Addr; Addr += FRAME_HORIZONTAL_LEN * FRAME_VERTICAL_LEN; } /* Set the buffer addresses for transfer in the DMA engine * The buffer addresses are physical addresses */ Status = XAxiVdma_DmaSetBufferAddr(InstancePtr, XAXIVDMA_READ, 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 InstancePtr is the instance pointer to the DMA engine. * * @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise. * * @note None. * ******************************************************************************/ static int WriteSetup(XAxiVdma * InstancePtr) { int Index; u32 Addr; int Status; WriteCfg.VertSizeInput = SUBFRAME_VERTICAL_SIZE; WriteCfg.HoriSizeInput = SUBFRAME_HORIZONTAL_SIZE; WriteCfg.Stride = FRAME_HORIZONTAL_LEN; WriteCfg.FrameDelay = 0; /* This example does not test frame delay */ WriteCfg.EnableCircularBuf = 1; WriteCfg.EnableSync = 0; /* No Gen-Lock */ WriteCfg.PointNum = 0; /* No Gen-Lock */ WriteCfg.EnableFrameCounter = 0; /* Endless transfers */ WriteCfg.FixedFrameStoreAddr = 0; /* We are not doing parking */ Status = XAxiVdma_DmaConfig(InstancePtr, XAXIVDMA_WRITE, &WriteCfg); if (Status != XST_SUCCESS) { xil_printf( "Write channel config failed %d\r\n", Status); return XST_FAILURE; } /* Initialize buffer addresses * * Use physical addresses */ Addr = WRITE_ADDRESS_BASE + BlockStartOffset; for(Index = 0; Index < NUMBER_OF_WRITE_FRAMES; Index++) { WriteCfg.FrameStoreStartAddr[Index] = Addr; Addr += FRAME_HORIZONTAL_LEN * FRAME_VERTICAL_LEN; } /* Set the buffer addresses for transfer in the DMA engine */ Status = XAxiVdma_DmaSetBufferAddr(InstancePtr, XAXIVDMA_WRITE, WriteCfg.FrameStoreStartAddr); if (Status != XST_SUCCESS) { xil_printf( "Write channel set buffer address failed %d\r\n", Status); return XST_FAILURE; } /* Clear data buffer */ memset((void *)WriteFrameAddr, 0, FRAME_HORIZONTAL_LEN * FRAME_VERTICAL_LEN * NUMBER_OF_WRITE_FRAMES); 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 succesfully * XST_FAILURE if one or both directions cannot be started * * @note None. * ******************************************************************************/ static int StartTransfer(XAxiVdma *InstancePtr) { int Status; Status = XAxiVdma_DmaStart(InstancePtr, XAXIVDMA_WRITE); if (Status != XST_SUCCESS) { xil_printf( "Start Write transfer failed %d\r\n", Status); return XST_FAILURE; } 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; } /*****************************************************************************/ /* * * 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; #ifdef XPAR_INTC_0_DEVICE_ID XIntc *IntcInstancePtr =&Intc; /* Initialize the interrupt controller and connect the ISRs */ Status = XIntc_Initialize(IntcInstancePtr, INTC_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(); #else XScuGic *IntcInstancePtr = &Intc; /* Instance of the Interrupt Controller */ XScuGic_Config *IntcConfig; /* * Initialize the interrupt controller driver so that it is ready to * use. */ IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); if (NULL == IntcConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } XScuGic_SetPriorityTriggerType(IntcInstancePtr, ReadIntrId, 0xA0, 0x3); XScuGic_SetPriorityTriggerType(IntcInstancePtr, WriteIntrId, 0xA0, 0x3); /* * Connect the device driver handler that will be called when an * interrupt for the device occurs, the handler defined above performs * the specific interrupt processing for the device. */ Status = XScuGic_Connect(IntcInstancePtr, ReadIntrId, (Xil_InterruptHandler)XAxiVdma_ReadIntrHandler, AxiVdmaPtr); if (Status != XST_SUCCESS) { return Status; } Status = XScuGic_Connect(IntcInstancePtr, WriteIntrId, (Xil_InterruptHandler)XAxiVdma_WriteIntrHandler, AxiVdmaPtr); if (Status != XST_SUCCESS) { return Status; } /* * Enable the interrupt for the DMA device. */ XScuGic_Enable(IntcInstancePtr, ReadIntrId); XScuGic_Enable(IntcInstancePtr, WriteIntrId); Xil_ExceptionInit(); /* * Connect the interrupt controller interrupt handler to the hardware * interrupt handling logic in the processor. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstancePtr); /* * Enable interrupts in the Processor. */ Xil_ExceptionEnable(); #endif 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) { #ifdef XPAR_INTC_0_DEVICE_ID XIntc *IntcInstancePtr =&Intc; /* Disconnect the interrupts for the DMA TX and RX channels */ XIntc_Disconnect(IntcInstancePtr, ReadIntrId); XIntc_Disconnect(IntcInstancePtr, WriteIntrId); #else XScuGic *IntcInstancePtr = &Intc; XScuGic_Disable(IntcInstancePtr, ReadIntrId); XScuGic_Disable(IntcInstancePtr, WriteIntrId); XScuGic_Disconnect(IntcInstancePtr, ReadIntrId); XScuGic_Disconnect(IntcInstancePtr, WriteIntrId); #endif } /*****************************************************************************/ /* * Call back function for read channel * * 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 ReadCallBack(void *CallbackRef, u32 Mask) { if (Mask & XAXIVDMA_IXR_FRMCNT_MASK) { ReadDone += 1; } } /*****************************************************************************/ /* * Call back function for read channel error interrupt * * @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) { if (Mask & XAXIVDMA_IXR_ERROR_MASK) { ReadError += 1; } } /*****************************************************************************/ /* * Call back function for write channel * * 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) { if (Mask & XAXIVDMA_IXR_FRMCNT_MASK) { WriteDone += 1; } } /*****************************************************************************/ /* * Call back function for write channel error interrupt * * @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) { if (Mask & XAXIVDMA_IXR_ERROR_MASK) { WriteError += 1; } }