embeddedsw/XilinxProcessorIPLib/drivers/axivdma/examples/xaxivdma_example_intr.c

914 lines
26 KiB
C
Raw Normal View History

/******************************************************************************
*
* 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.
*
* <pre>
* 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).
* </pre>
*
* ***************************************************************************
*/
#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;
}
}