dma: Add axidma_v8_1 and deprecate axidma_v8_0

This patch add's new version of the axidma driver
and deprecates the older version of the driver.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
This commit is contained in:
Kedareswara rao Appana 2015-01-20 17:18:12 +05:30 committed by Suneel Garapati
parent adbfea517d
commit 0f604c9902
21 changed files with 10904 additions and 0 deletions

View file

@ -0,0 +1,43 @@
###############################################################################
#
# Copyright (C) 2010 - 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.
#
##############################################################################
OPTION psf_version = 2.1;
BEGIN driver axidma
OPTION supported_peripherals = (axi_dma_v[3-9]_[0-9][0-9]_[a-z] axi_dma_v[3-9]_[0-9]);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 8.1;
OPTION NAME = axidma;
END driver

View file

@ -0,0 +1,208 @@
###############################################################################
#
# Copyright (C) 2010 - 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.
#
# MODIFICATION HISTORY:
# Ver Who Date Changes
# -------- ------ -------- ----------------------------------------------------
# 8.0 adk 12/10/13 Updated as per the New Tcl API's
##############################################################################
#uses "xillib.tcl"
set periph_ninstances 0
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "XAxiDma" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S_DRE" "C_INCLUDE_S2MM_DRE" "C_INCLUDE_MM2S" "C_INCLUDE_S2MM" "C_M_AXI_MM2S_DATA_WIDTH" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_ENABLE_MULTI_CHANNEL" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA"
xdefine_canonical_xpars $drv_handle "xparameters.h" "AxiDma" "DEVICE_ID" "C_BASEADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S" "C_INCLUDE_MM2S_DRE" "C_M_AXI_MM2S_DATA_WIDTH" "C_INCLUDE_S2MM" "C_INCLUDE_S2MM_DRE" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_ENABLE_MULTI_CHANNEL" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA"
xdefine_config_file $drv_handle "xaxidma_g.c" "XAxiDma" "DEVICE_ID" "C_BASEADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S" "C_INCLUDE_MM2S_DRE" "C_M_AXI_MM2S_DATA_WIDTH" "C_INCLUDE_S2MM" "C_INCLUDE_S2MM_DRE" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA"
}
#
# Given a list of arguments, define them all in an include file.
# Handles mpd and mld parameters, as well as the special parameters NUM_INSTANCES,
# DEVICE_ID
# Will not work for a processor.
#
proc xdefine_dma_include_file {drv_handle file_name drv_string args} {
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Handle special cases
set arg "NUM_INSTANCES"
set posn [lsearch -exact $args $arg]
if {$posn > -1} {
puts $file_handle "/* Definitions for driver [string toupper [get_property NAME $drv_handle]] */"
# Define NUM_INSTANCES
puts $file_handle "#define [xget_dname $drv_string $arg] [llength $periphs]"
set args [lreplace $args $posn $posn]
}
# Check if it is a driver parameter
lappend newargs
foreach arg $args {
set value [get_property CONFIG.$arg $drv_handle]
if {[llength $value] == 0} {
lappend newargs $arg
} else {
puts $file_handle "#define [xget_dname $drv_string $arg] [get_property CONFIG.$arg $drv_handle]"
}
}
set args $newargs
# Print all parameters for all peripherals
set device_id 0
foreach periph $periphs {
puts $file_handle ""
puts $file_handle "/* Definitions for peripheral [string toupper [get_property NAME $periph]] */"
foreach arg $args {
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
set value $device_id
incr device_id
} else {
set value [xget_param_value $periph $arg]
if {[string compare -nocase $arg "C_INCLUDE_SG"] == 0} {
if {[llength $value] == 0} {
set value 1
}
} else {
if {[llength $value] == 0} {
set value 0
}
}
if {[string compare -nocase $arg "C_MICRO_DMA"] == 0} {
if {[llength $value] == 0} {
set value 1
}
} else {
if {[llength $value] == 0} {
set value 0
}
}
}
set value [xformat_addr_string $value $arg]
if {[string compare -nocase "HW_VER" $arg] == 0} {
puts $file_handle "#define [xget_name $periph $arg] \"$value\""
} else {
puts $file_handle "#define [xget_name $periph $arg] $value"
}
}
puts $file_handle ""
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
#-----------------------------------------------------------------------------
# xdefine_canonical_xpars - Used to print out canonical defines for a driver.
# Given a list of arguments, define each as a canonical constant name, using
# the driver name, in an include file.
#-----------------------------------------------------------------------------
proc xdefine_axidma_canonical_xpars {drv_handle file_name drv_string args} {
# Open include file
set file_handle [xopen_include_file $file_name]
# Get all the peripherals connected to this driver
set periphs [xget_sw_iplist_for_driver $drv_handle]
# Get the names of all the peripherals connected to this driver
foreach periph $periphs {
set peripheral_name [string toupper [get_property NAME $periph]]
lappend peripherals $peripheral_name
}
# Get possible canonical names for all the peripherals connected to this
# driver
set device_id 0
foreach periph $periphs {
set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]]
lappend canonicals $canonical_name
# Create a list of IDs of the peripherals whose hardware instance name
# doesn't match the canonical name. These IDs can be used later to
# generate canonical definitions
if { [lsearch $peripherals $canonical_name] < 0 } {
lappend indices $device_id
}
incr device_id
}
set i 0
foreach periph $periphs {
set periph_name [string toupper [get_property NAME $periph]]
# Generate canonical definitions only for the peripherals whose
# canonical name is not the same as hardware instance name
if { [lsearch $canonicals $periph_name] < 0 } {
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]]
foreach arg $args {
set lvalue [xget_dname $canonical_name $arg]
# The commented out rvalue is the name of the instance-specific constant
# set rvalue [xget_name $periph $arg]
# The rvalue set below is the actual value of the parameter
set rvalue [xget_param_value $periph $arg]
if {[string compare -nocase $arg "C_INCLUDE_SG"] == 0} {
if {[llength $rvalue] == 0} {
set rvalue 1
}
} else {
if {[llength $rvalue] == 0} {
set rvalue 0
}
}
if {[string compare -nocase $arg "C_MICRO_DMA"] == 0} {
if {[llength $rvalue] == 0} {
set rvalue 1
}
} else {
if {[llength $rvalue] == 0} {
set rvalue 0
}
}
set rvalue [xformat_addr_string $rvalue $arg]
puts $file_handle "#define $lvalue $rvalue"
}
puts $file_handle ""
incr i
}
}
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example Applications for the driver axidma_v8_0 </h1>
<HR>
<ul>
<li>xaxidma_example_sg_intr.c <a href="xaxidma_example_sg_intr.c">(source)</a> </li>
<li>xaxidma_example_sg_poll.c <a href="xaxidma_example_sg_poll.c">(source)</a> </li>
<li>xaxidma_example_simple_intr.c <a href="xaxidma_example_simple_intr.c">(source)</a> </li>
<li>xaxidma_example_simple_poll.c <a href="xaxidma_example_simple_poll.c">(source)</a> </li>
<li>xaxidma_poll_multi_pkts.c <a href="xaxidma_poll_multi_pkts.c">(source)</a> </li>
<li>xaxidma_multichan_sg_intr.c <a href="xaxidma_multichan_sg_intr.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright <20> 1995-2014 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,688 @@
/******************************************************************************
*
* (c) Copyright 2010-2013 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxidma_example_sg_poll.c
*
* This file demonstrates how to use the xaxidma driver on the Xilinx AXI
* DMA core (AXIDMA) to transfer packets in polling mode when the AXIDMA
* core is configured in Scatter Gather Mode.
*
* This code assumes a loopback hardware widget is connected to the AXI DMA
* core for data packet loopback.
*
* 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.
*
* Make sure that MEMORY_BASE is defined properly as per the HW system. The
* h/w system built in Area mode has a maximum DDR memory limit of 64MB. In
* throughput mode, it is 512MB. These limits are need to ensured for
* proper operation of this code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/17/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h, removed
* workaround for endianness
* 4.00a rkv 02/22/11 Name of the file has been changed for naming consistency
* Added interrupt support for ARM.
* 5.00a srt 03/05/12 Added Flushing and Invalidation of Caches to fix CRs
* 648103, 648701.
* Added V7 DDR Base Address to fix CR 649405.
* 6.00a srt 03/27/12 Changed API calls to support MCDMA driver.
* 7.00a srt 06/18/12 API calls are reverted back for backward compatibility.
* 7.01a srt 11/02/12 Buffer sizes (Tx and Rx) are modified to meet maximum
* DDR memory limit of the h/w system built with Area mode
* 7.02a srt 03/01/13 Updated DDR base address for IPI designs (CR 703656).
*
* </pre>
*
* ***************************************************************************
*/
/***************************** Include Files *********************************/
#include "xaxidma.h"
#include "xparameters.h"
#include "xdebug.h"
#if defined(XPAR_UARTNS550_0_BASEADDR)
#include "xuartns550_l.h" /* to use uartns550 */
#endif
#if (!defined(DEBUG))
extern void xil_printf(const char *format, ...);
#endif
/******************** Constant Definitions **********************************/
/*
* Device hardware build related constants.
*/
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#ifdef XPAR_V6DDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_V6DDR_0_S_AXI_BASEADDR
#elif XPAR_S6DDR_0_S0_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_S6DDR_0_S0_AXI_BASEADDR
#elif XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR
#endif
#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR 0x01000000
#else
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000)
#endif
#define TX_BD_SPACE_BASE (MEM_BASE_ADDR)
#define TX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00000FFF)
#define RX_BD_SPACE_BASE (MEM_BASE_ADDR + 0x00001000)
#define RX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00001FFF)
#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x004FFFFF)
#define MAX_PKT_LEN 0x20
#define TEST_START_VALUE 0xC
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#if defined(XPAR_UARTNS550_0_BASEADDR)
static void Uart550_Setup(void);
#endif
static int RxSetup(XAxiDma * AxiDmaInstPtr);
static int TxSetup(XAxiDma * AxiDmaInstPtr);
static int SendPacket(XAxiDma * AxiDmaInstPtr);
static int CheckData(void);
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr);
/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
XAxiDma AxiDma;
/*
* Buffer for transmit packet. Must be 32-bit aligned to be used by DMA.
*/
u32 *Packet = (u32 *) TX_BUFFER_BASE;
/*****************************************************************************/
/**
*
* Main function
*
* This function is the main entry of the tests on DMA core. It sets up
* DMA engine to be ready to receive and send packets, then a packet is
* transmitted and will be verified after it is received via the DMA loopback
* widget.
*
* @param None
*
* @return
* - XST_SUCCESS if test passes
* - XST_FAILURE if test fails.
*
* @note None.
*
******************************************************************************/
int main(void)
{
int Status;
XAxiDma_Config *Config;
#if defined(XPAR_UARTNS550_0_BASEADDR)
Uart550_Setup();
#endif
xil_printf("\r\n--- Entering main() --- \r\n");
Config = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!Config) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
/* Initialize DMA engine */
Status = XAxiDma_CfgInitialize(&AxiDma, Config);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}
if(!XAxiDma_HasSg(&AxiDma)) {
xil_printf("Device configured as Simple mode \r\n");
return XST_FAILURE;
}
Status = TxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = RxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Send a packet */
Status = SendPacket(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Check DMA transfer result */
Status = CheckDmaResult(&AxiDma);
xil_printf("AXI DMA SG Polling Test %s\r\n",
(Status == XST_SUCCESS)? "passed":"failed");
xil_printf("--- Exiting main() --- \r\n");
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600, and data bits to 8
*
* @param None
*
* @return None
*
* @note None.
*
******************************************************************************/
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
/*****************************************************************************/
/**
*
* This function sets up RX channel of the DMA engine to be ready for packet
* reception
*
* @param AxiDmaInstPtr is the pointer to the instance of the DMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int RxSetup(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *RxRingPtr;
int Delay = 0;
int Coalesce = 1;
int Status;
XAxiDma_Bd BdTemplate;
XAxiDma_Bd *BdPtr;
XAxiDma_Bd *BdCurPtr;
u32 BdCount;
u32 FreeBdCount;
u32 RxBufferPtr;
int Index;
RxRingPtr = XAxiDma_GetRxRing(&AxiDma);
/* Disable all RX interrupts before RxBD space setup */
XAxiDma_BdRingIntDisable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/* Set delay and coalescing */
XAxiDma_BdRingSetCoalesce(RxRingPtr, Coalesce, Delay);
/* Setup Rx BD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
RX_BD_SPACE_HIGH - RX_BD_SPACE_BASE + 1);
Status = XAxiDma_BdRingCreate(RxRingPtr, RX_BD_SPACE_BASE,
RX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);
if (Status != XST_SUCCESS) {
xil_printf("RX create BD ring failed %d\r\n", Status);
return XST_FAILURE;
}
/*
* Setup an all-zero BD as the template for the Rx channel.
*/
XAxiDma_BdClear(&BdTemplate);
Status = XAxiDma_BdRingClone(RxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xil_printf("RX clone BD failed %d\r\n", Status);
return XST_FAILURE;
}
/* Attach buffers to RxBD ring so we are ready to receive packets */
FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);
Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX alloc BD failed %d\r\n", Status);
return XST_FAILURE;
}
BdCurPtr = BdPtr;
RxBufferPtr = RX_BUFFER_BASE;
for (Index = 0; Index < FreeBdCount; Index++) {
Status = XAxiDma_BdSetBufAddr(BdCurPtr, RxBufferPtr);
if (Status != XST_SUCCESS) {
xil_printf("Set buffer addr %x on BD %x failed %d\r\n",
(unsigned int)RxBufferPtr,
(unsigned int)BdCurPtr, Status);
return XST_FAILURE;
}
Status = XAxiDma_BdSetLength(BdCurPtr, MAX_PKT_LEN,
RxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Rx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (unsigned int)BdCurPtr, Status);
return XST_FAILURE;
}
/* Receive BDs do not need to set anything for the control
* The hardware will set the SOF/EOF bits per stream status
*/
XAxiDma_BdSetCtrl(BdCurPtr, 0);
XAxiDma_BdSetId(BdCurPtr, RxBufferPtr);
RxBufferPtr += MAX_PKT_LEN;
BdCurPtr = XAxiDma_BdRingNext(RxRingPtr, BdCurPtr);
}
/* Clear the receive buffer, so we can verify data
*/
memset((void *)RX_BUFFER_BASE, 0, MAX_PKT_LEN);
Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount,
BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX submit hw failed %d\r\n", Status);
return XST_FAILURE;
}
/* Start RX DMA channel */
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX start hw failed %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function sets up the TX channel of a DMA engine to be ready for packet
* transmission
*
* @param AxiDmaInstPtr is the instance pointer to the DMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int TxSetup(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_Bd BdTemplate;
int Delay = 0;
int Coalesce = 1;
int Status;
u32 BdCount;
TxRingPtr = XAxiDma_GetTxRing(&AxiDma);
/* Disable all TX interrupts before TxBD space setup */
XAxiDma_BdRingIntDisable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/* Set TX delay and coalesce */
XAxiDma_BdRingSetCoalesce(TxRingPtr, Coalesce, Delay);
/* Setup TxBD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
TX_BD_SPACE_HIGH - TX_BD_SPACE_BASE + 1);
Status = XAxiDma_BdRingCreate(TxRingPtr, TX_BD_SPACE_BASE,
TX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);
if (Status != XST_SUCCESS) {
xil_printf("failed create BD ring in txsetup\r\n");
return XST_FAILURE;
}
/*
* We create an all-zero BD as the template.
*/
XAxiDma_BdClear(&BdTemplate);
Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xil_printf("failed bdring clone in txsetup %d\r\n", Status);
return XST_FAILURE;
}
/* Start the TX channel */
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
xil_printf("failed start bdring txsetup %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function transmits one packet non-blockingly through the DMA engine.
*
* @param AxiDmaInstPtr points to the DMA engine instance
*
* @return - XST_SUCCESS if the DMA accepts the packet successfully,
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int SendPacket(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
u8 *TxPacket;
u8 Value;
XAxiDma_Bd *BdPtr;
int Status;
int Index;
TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
/* Create pattern in the packet to transmit */
TxPacket = (u8 *) Packet;
Value = TEST_START_VALUE;
for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxPacket[Index] = Value;
Value = (Value + 1) & 0xFF;
}
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)TxPacket, MAX_PKT_LEN);
/* Allocate a BD */
Status = XAxiDma_BdRingAlloc(TxRingPtr, 1, &BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Set up the BD using the information of the packet to transmit */
Status = XAxiDma_BdSetBufAddr(BdPtr, (u32) Packet);
if (Status != XST_SUCCESS) {
xil_printf("Tx set buffer addr %x on BD %x failed %d\r\n",
(unsigned int)Packet, (unsigned int)BdPtr, Status);
return XST_FAILURE;
}
Status = XAxiDma_BdSetLength(BdPtr, MAX_PKT_LEN,
TxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Tx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (unsigned int)BdPtr, Status);
return XST_FAILURE;
}
#if (XPAR_AXIDMA_0_SG_INCLUDE_STSCNTRL_STRM == 1)
Status = XAxiDma_BdSetAppWord(BdPtr,
XAXIDMA_LAST_APPWORD, MAX_PKT_LEN);
/* If Set app length failed, it is not fatal
*/
if (Status != XST_SUCCESS) {
xil_printf("Set app word failed with %d\r\n", Status);
}
#endif
/* For single packet, both SOF and EOF are to be set
*/
XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXEOF_MASK |
XAXIDMA_BD_CTRL_TXSOF_MASK);
XAxiDma_BdSetId(BdPtr, (u32) Packet);
/* Give the BD to DMA to kick off the transmission. */
Status = XAxiDma_BdRingToHw(TxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("to hw failed %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param None
*
* @return - XST_SUCCESS if validation is successful
* - XST_FAILURE if validation is failure.
*
* @note None.
*
******************************************************************************/
static int CheckData(void)
{
u8 *RxPacket;
int Index = 0;
u8 Value;
RxPacket = (u8 *) RX_BUFFER_BASE;
Value = TEST_START_VALUE;
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((u32)RxPacket, MAX_PKT_LEN);
for(Index = 0; Index < MAX_PKT_LEN; Index++) {
if (RxPacket[Index] != Value) {
xil_printf("Data error %d: %x/%x\r\n",
Index, (unsigned int)RxPacket[Index],
(unsigned int)Value);
return XST_FAILURE;
}
Value = (Value + 1) & 0xFF;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function waits until the DMA transaction is finished, checks data,
* and cleans up.
*
* @param None
*
* @return - XST_SUCCESS if DMA transfer is successful and data is correct,
* - XST_FAILURE if fails.
*
* @note None.
*
******************************************************************************/
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
XAxiDma_Bd *BdPtr;
int ProcessedBdCount;
int FreeBdCount;
int Status;
TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr);
/* Wait until the one BD TX transaction is done */
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(TxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}
/* Free all processed TX BDs for future transmission */
Status = XAxiDma_BdRingFree(TxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed to free %d tx BDs %d\r\n",
ProcessedBdCount, Status);
return XST_FAILURE;
}
/* Wait until the data has been received by the Rx channel */
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}
/* Check received data */
if (CheckData() != XST_SUCCESS) {
return XST_FAILURE;
}
/* Free all processed RX BDs for future transmission */
Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed to free %d rx BDs %d\r\n",
ProcessedBdCount, Status);
return XST_FAILURE;
}
/* Return processed BDs to RX channel so we are ready to receive new
* packets:
* - Allocate all free RX BDs
* - Pass the BDs to RX channel
*/
FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);
Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("bd alloc failed\r\n");
return XST_FAILURE;
}
Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Submit %d rx BDs failed %d\r\n", FreeBdCount, Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,748 @@
/******************************************************************************
*
* (c) Copyright 2010-2013 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxidma_example_simple_intr.c
*
* This file demonstrates how to use the xaxidma driver on the Xilinx AXI
* DMA core (AXIDMA) to transfer packets.in interrupt mode when the AXIDMA core
* is configured in simple mode
*
* This code assumes a loopback hardware widget is connected to the AXI DMA
* core for data packet loopback.
*
* 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.
*
* Make sure that MEMORY_BASE is defined properly as per the HW system. The
* h/w system built in Area mode has a maximum DDR memory limit of 64MB. In
* throughput mode, it is 512MB. These limits are need to ensured for
* proper operation of this code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 4.00a rkv 02/22/11 New example created for simple DMA, this example is for
* simple DMA,Added interrupt support for Zynq.
* 4.00a srt 08/04/11 Changed a typo in the RxIntrHandler, changed
* XAXIDMA_DMA_TO_DEVICE to XAXIDMA_DEVICE_TO_DMA
* 5.00a srt 03/06/12 Added Flushing and Invalidation of Caches to fix CRs
* 648103, 648701.
* Added V7 DDR Base Address to fix CR 649405.
* 6.00a srt 03/27/12 Changed API calls to support MCDMA driver.
* 7.00a srt 06/18/12 API calls are reverted back for backward compatibility.
* 7.01a srt 11/02/12 Buffer sizes (Tx and Rx) are modified to meet maximum
* DDR memory limit of the h/w system built with Area mode
* 7.02a srt 03/01/13 Updated DDR base address for IPI designs (CR 703656).
*
* </pre>
*
* ***************************************************************************
*/
/***************************** Include Files *********************************/
#include "xaxidma.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xdebug.h"
#ifdef XPAR_UARTNS550_0_BASEADDR
#include "xuartns550_l.h" /* to use uartns550 */
#endif
#ifdef XPAR_INTC_0_DEVICE_ID
#include "xintc.h"
#else
#include "xscugic.h"
#endif
/************************** Constant Definitions *****************************/
/*
* Device hardware build related constants.
*/
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#ifdef XPAR_V6DDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_V6DDR_0_S_AXI_BASEADDR
#elif XPAR_S6DDR_0_S0_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_S6DDR_0_S0_AXI_BASEADDR
#elif XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR
#endif
#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR 0x01000000
#else
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000)
#endif
#ifdef XPAR_INTC_0_DEVICE_ID
#define RX_INTR_ID XPAR_INTC_0_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define TX_INTR_ID XPAR_INTC_0_AXIDMA_0_MM2S_INTROUT_VEC_ID
#else
#define RX_INTR_ID XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define TX_INTR_ID XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID
#endif
#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x004FFFFF)
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#else
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif
/* Timeout loop counter for reset
*/
#define RESET_TIMEOUT_COUNTER 10000
#define TEST_START_VALUE 0xC
/*
* Buffer and Buffer Descriptor related constant definition
*/
#define MAX_PKT_LEN 0x100
#define NUMBER_OF_TRANSFERS 10
/* The interrupt coalescing threshold and delay timer threshold
* Valid range is 1 to 255
*
* We set the coalescing threshold to be the total number of packets.
* The receive side will only get one completion interrupt for this example.
*/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#ifndef DEBUG
extern void xil_printf(const char *format, ...);
#endif
#ifdef XPAR_UARTNS550_0_BASEADDR
static void Uart550_Setup(void);
#endif
static int CheckData(int Length, u8 StartValue);
static void TxIntrHandler(void *Callback);
static void RxIntrHandler(void *Callback);
static int SetupIntrSystem(INTC * IntcInstancePtr,
XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId);
static void DisableIntrSystem(INTC * IntcInstancePtr,
u16 TxIntrId, u16 RxIntrId);
/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
static XAxiDma AxiDma; /* Instance of the XAxiDma */
static INTC Intc; /* Instance of the Interrupt Controller */
/*
* Flags interrupt handlers use to notify the application context the events.
*/
volatile int TxDone;
volatile int RxDone;
volatile int Error;
/*****************************************************************************/
/**
*
* Main function
*
* This function is the main entry of the interrupt test. It does the following:
* Set up the output terminal if UART16550 is in the hardware build
* Initialize the DMA engine
* Set up Tx and Rx channels
* Set up the interrupt system for the Tx and Rx interrupts
* Submit a transfer
* Wait for the transfer to finish
* Check transfer status
* Disable Tx and Rx interrupts
* Print test status and exit
*
* @param None
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if example fails.
*
* @note None.
*
******************************************************************************/
int main(void)
{
int Status;
XAxiDma_Config *Config;
int Tries = NUMBER_OF_TRANSFERS;
int Index;
u8 *TxBufferPtr;
u8 *RxBufferPtr;
u8 Value;
TxBufferPtr = (u8 *)TX_BUFFER_BASE ;
RxBufferPtr = (u8 *)RX_BUFFER_BASE;
/* Initial setup for Uart16550 */
#ifdef XPAR_UARTNS550_0_BASEADDR
Uart550_Setup();
#endif
xil_printf("\r\n--- Entering main() --- \r\n");
Config = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!Config) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
/* Initialize DMA engine */
Status = XAxiDma_CfgInitialize(&AxiDma, Config);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}
if(XAxiDma_HasSg(&AxiDma)){
xil_printf("Device configured as SG mode \r\n");
return XST_FAILURE;
}
/* Set up Interrupt system */
Status = SetupIntrSystem(&Intc, &AxiDma, TX_INTR_ID, RX_INTR_ID);
if (Status != XST_SUCCESS) {
xil_printf("Failed intr setup\r\n");
return XST_FAILURE;
}
/* Disable all interrupts before setup */
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DMA_TO_DEVICE);
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DEVICE_TO_DMA);
/* Enable all interrupts */
XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DMA_TO_DEVICE);
XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DEVICE_TO_DMA);
/* Initialize flags before start transfer test */
TxDone = 0;
RxDone = 0;
Error = 0;
Value = TEST_START_VALUE;
for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxBufferPtr[Index] = Value;
Value = (Value + 1) & 0xFF;
}
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);
/* Send a packet */
for(Index = 0; Index < Tries; Index ++) {
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait TX done and RX done
*/
while (!TxDone && !RxDone && !Error) {
/* NOP */
}
if (Error) {
xil_printf("Failed test transmit%s done, "
"receive%s done\r\n", TxDone? "":" not",
RxDone? "":" not");
goto Done;
}
/*
* Test finished, check data
*/
Status = CheckData(MAX_PKT_LEN, 0xC);
if (Status != XST_SUCCESS) {
xil_printf("Data check failed\r\n");
goto Done;
}
}
xil_printf("AXI DMA interrupt example test passed\r\n");
/* Disable TX and RX Ring interrupts and return success */
DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);
Done:
xil_printf("--- Exiting main() --- \r\n");
return XST_SUCCESS;
}
#ifdef XPAR_UARTNS550_0_BASEADDR
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600 and data bits to 8
*
* @param None
*
* @return None
*
* @note None.
*
******************************************************************************/
static void Uart550_Setup(void)
{
XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR,
XPAR_XUARTNS550_CLOCK_HZ, 9600);
XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR,
XUN_LCR_8_DATA_BITS);
}
#endif
/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* We use the static tx/rx buffers.
*
* @param Length is the length to check
* @param StartValue is the starting value of the first byte
*
* @return
* - XST_SUCCESS if validation is successful
* - XST_FAILURE if validation is failure.
*
* @note None.
*
******************************************************************************/
static int CheckData(int Length, u8 StartValue)
{
u8 *RxPacket;
int Index = 0;
u8 Value;
RxPacket = (u8 *) RX_BUFFER_BASE;
Value = StartValue;
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((u32)RxPacket, Length);
for(Index = 0; Index < Length; Index++) {
if (RxPacket[Index] != Value) {
xil_printf("Data error %d: %x/%x\r\n",
Index, RxPacket[Index], Value);
return XST_FAILURE;
}
Value = (Value + 1) & 0xFF;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
*
* This is the DMA TX Interrupt handler function.
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then sets the TxDone.flag
*
* @param Callback is a pointer to TX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void TxIntrHandler(void *Callback)
{
u32 IrqStatus;
int TimeOut;
XAxiDma *AxiDmaInst = (XAxiDma *)Callback;
/* Read pending interrupts */
IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DMA_TO_DEVICE);
/* Acknowledge pending interrupts */
XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DMA_TO_DEVICE);
/*
* If no interrupt is asserted, we do not do anything
*/
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
return;
}
/*
* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
Error = 1;
/*
* Reset should never fail for transmit channel
*/
XAxiDma_Reset(AxiDmaInst);
TimeOut = RESET_TIMEOUT_COUNTER;
while (TimeOut) {
if (XAxiDma_ResetIsDone(AxiDmaInst)) {
break;
}
TimeOut -= 1;
}
return;
}
/*
* If Completion interrupt is asserted, then set the TxDone flag
*/
if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
TxDone = 1;
}
}
/*****************************************************************************/
/*
*
* This is the DMA RX interrupt handler function
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then it sets the RxDone flag.
*
* @param Callback is a pointer to RX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void RxIntrHandler(void *Callback)
{
u32 IrqStatus;
int TimeOut;
XAxiDma *AxiDmaInst = (XAxiDma *)Callback;
/* Read pending interrupts */
IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA);
/* Acknowledge pending interrupts */
XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);
/*
* If no interrupt is asserted, we do not do anything
*/
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
return;
}
/*
* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
Error = 1;
/* Reset could fail and hang
* NEED a way to handle this or do not call it??
*/
XAxiDma_Reset(AxiDmaInst);
TimeOut = RESET_TIMEOUT_COUNTER;
while (TimeOut) {
if(XAxiDma_ResetIsDone(AxiDmaInst)) {
break;
}
TimeOut -= 1;
}
return;
}
/*
* If completion interrupt is asserted, then set RxDone flag
*/
if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
RxDone = 1;
}
}
/*****************************************************************************/
/*
*
* This function setups the interrupt system so interrupts can occur for the
* DMA, it assumes INTC component exists in the hardware system.
*
* @param IntcInstancePtr is a pointer to the instance of the INTC.
* @param AxiDmaPtr is a pointer to the instance of the DMA engine
* @param TxIntrId is the TX channel Interrupt ID.
* @param RxIntrId is the RX channel Interrupt ID.
*
* @return
* - XST_SUCCESS if successful,
* - XST_FAILURE.if not succesful
*
* @note None.
*
******************************************************************************/
static int SetupIntrSystem(INTC * IntcInstancePtr,
XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId)
{
int Status;
#ifdef XPAR_INTC_0_DEVICE_ID
/* 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, TxIntrId,
(XInterruptHandler) TxIntrHandler, AxiDmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed tx connect intc\r\n");
return XST_FAILURE;
}
Status = XIntc_Connect(IntcInstancePtr, RxIntrId,
(XInterruptHandler) RxIntrHandler, AxiDmaPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed rx connect intc\r\n");
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;
}
XIntc_Enable(IntcInstancePtr, TxIntrId);
XIntc_Enable(IntcInstancePtr, RxIntrId);
#else
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, TxIntrId, 0xA0, 0x3);
XScuGic_SetPriorityTriggerType(IntcInstancePtr, RxIntrId, 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, TxIntrId,
(Xil_InterruptHandler)TxIntrHandler,
AxiDmaPtr);
if (Status != XST_SUCCESS) {
return Status;
}
Status = XScuGic_Connect(IntcInstancePtr, RxIntrId,
(Xil_InterruptHandler)RxIntrHandler,
AxiDmaPtr);
if (Status != XST_SUCCESS) {
return Status;
}
XScuGic_Enable(IntcInstancePtr, TxIntrId);
XScuGic_Enable(IntcInstancePtr, RxIntrId);
#endif
/* Enable interrupts from the hardware */
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts for DMA engine.
*
* @param IntcInstancePtr is the pointer to the INTC component instance
* @param TxIntrId is interrupt ID associated w/ DMA TX channel
* @param RxIntrId is interrupt ID associated w/ DMA RX channel
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void DisableIntrSystem(INTC * IntcInstancePtr,
u16 TxIntrId, u16 RxIntrId)
{
#ifdef XPAR_INTC_0_DEVICE_ID
/* Disconnect the interrupts for the DMA TX and RX channels */
XIntc_Disconnect(IntcInstancePtr, TxIntrId);
XIntc_Disconnect(IntcInstancePtr, RxIntrId);
#else
XScuGic_Disconnect(IntcInstancePtr, TxIntrId);
XScuGic_Disconnect(IntcInstancePtr, RxIntrId);
#endif
}

View file

@ -0,0 +1,357 @@
/******************************************************************************
*
* (c) Copyright 2010-2013 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxidma_example_simple_poll.c
*
* This file demonstrates how to use the xaxidma driver on the Xilinx AXI
* DMA core (AXIDMA) to transfer packets in polling mode when the AXI DMA core
* is configured in simple mode.
*
* This code assumes a loopback hardware widget is connected to the AXI DMA
* core for data packet loopback.
*
* 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.
*
* Make sure that MEMORY_BASE is defined properly as per the HW system. The
* h/w system built in Area mode has a maximum DDR memory limit of 64MB. In
* throughput mode, it is 512MB. These limits are need to ensured for
* proper operation of this code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 4.00a rkv 02/22/11 New example created for simple DMA, this example is for
* simple DMA
* 5.00a srt 03/06/12 Added Flushing and Invalidation of Caches to fix CRs
* 648103, 648701.
* Added V7 DDR Base Address to fix CR 649405.
* 6.00a srt 03/27/12 Changed API calls to support MCDMA driver.
* 7.00a srt 06/18/12 API calls are reverted back for backward compatibility.
* 7.01a srt 11/02/12 Buffer sizes (Tx and Rx) are modified to meet maximum
* DDR memory limit of the h/w system built with Area mode
* 7.02a srt 03/01/13 Updated DDR base address for IPI designs (CR 703656).
*
* </pre>
*
* ***************************************************************************
*/
/***************************** Include Files *********************************/
#include "xaxidma.h"
#include "xparameters.h"
#include "xdebug.h"
#if defined(XPAR_UARTNS550_0_BASEADDR)
#include "xuartns550_l.h" /* to use uartns550 */
#endif
/******************** Constant Definitions **********************************/
/*
* Device hardware build related constants.
*/
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#ifdef XPAR_V6DDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_V6DDR_0_S_AXI_BASEADDR
#elif XPAR_S6DDR_0_S0_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_S6DDR_0_S0_AXI_BASEADDR
#elif XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR
#endif
#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR 0x01000000
#else
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000)
#endif
#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x004FFFFF)
#define MAX_PKT_LEN 0x20
#define TEST_START_VALUE 0xC
#define NUMBER_OF_TRANSFERS 10
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#if (!defined(DEBUG))
extern void xil_printf(const char *format, ...);
#endif
int XAxiDma_SimplePollExample(u16 DeviceId);
static int CheckData(void);
/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
XAxiDma AxiDma;
/*****************************************************************************/
/*
* The entry point for this example. It invokes the example function,
* and reports the execution status.
*
* @param None.
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if example fails.
*
* @note None.
*
******************************************************************************/
int main()
{
int Status;
xil_printf("\r\n--- Entering main() --- \r\n");
/* Run the poll example for simple transfer */
Status = XAxiDma_SimplePollExample(DMA_DEV_ID);
if (Status != XST_SUCCESS) {
xil_printf("XAxiDma_SimplePollExample: Failed\r\n");
return XST_FAILURE;
}
xil_printf("XAxiDma_SimplePollExample: Passed\r\n");
xil_printf("--- Exiting main() --- \r\n");
return XST_SUCCESS;
}
#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600, and data bits to 8
*
* @param None.
*
* @return None
*
* @note None.
*
******************************************************************************/
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
/*****************************************************************************/
/**
* The example to do the simple transfer through polling. The constant
* NUMBER_OF_TRANSFERS defines how many times a simple transfer is repeated.
*
* @param DeviceId is the Device Id of the XAxiDma instance
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if error occurs
*
* @note None
*
*
******************************************************************************/
int XAxiDma_SimplePollExample(u16 DeviceId)
{
XAxiDma_Config *CfgPtr;
int Status;
int Tries = NUMBER_OF_TRANSFERS;
int Index;
u8 *TxBufferPtr;
u8 *RxBufferPtr;
u8 Value;
TxBufferPtr = (u8 *)TX_BUFFER_BASE ;
RxBufferPtr = (u8 *)RX_BUFFER_BASE;
/* Initialize the XAxiDma device.
*/
CfgPtr = XAxiDma_LookupConfig(DeviceId);
if (!CfgPtr) {
xil_printf("No config found for %d\r\n", DeviceId);
return XST_FAILURE;
}
Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}
if(XAxiDma_HasSg(&AxiDma)){
xil_printf("Device configured as SG mode \r\n");
return XST_FAILURE;
}
/* Disable interrupts, we use polling mode
*/
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
XAXIDMA_DMA_TO_DEVICE);
Value = TEST_START_VALUE;
for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxBufferPtr[Index] = Value;
Value = (Value + 1) & 0xFF;
}
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);
for(Index = 0; Index < Tries; Index ++) {
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
while ((XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) ||
(XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE))) {
/* Wait */
}
Status = CheckData();
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
}
/* Test finishes successfully
*/
return XST_SUCCESS;
}
/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param None
*
* @return
* - XST_SUCCESS if validation is successful.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int CheckData(void)
{
u8 *RxPacket;
int Index = 0;
u8 Value;
RxPacket = (u8 *) RX_BUFFER_BASE;
Value = TEST_START_VALUE;
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((u32)RxPacket, MAX_PKT_LEN);
for(Index = 0; Index < MAX_PKT_LEN; Index++) {
if (RxPacket[Index] != Value) {
xil_printf("Data error %d: %x/%x\r\n",
Index, (unsigned int)RxPacket[Index],
(unsigned int)Value);
return XST_FAILURE;
}
Value = (Value + 1) & 0xFF;
}
return XST_SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,696 @@
/******************************************************************************
*
* (c) Copyright 2010-2013 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxidma_poll_multi_pkts.c
*
* This file demonstrates how to use the xaxidma driver on the Xilinx AXI
* DMA core (AXIDMA) to transfer multiple packets in polling mode when the
* AXI DMA core is configured in Scatter Gather Mode.
*
* This code assumes a loopback hardware widget is connected to the AXI DMA
* core for data packet loopback.
*
* 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.
*
* Make sure that MEMORY_BASE is defined properly as per the HW system. The
* h/w system built in Area mode has a maximum DDR memory limit of 64MB. In
* throughput mode, it is 512MB. These limits are need to ensured for
* proper operation of this code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/17/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h, removed
* workaround for endianness
* 4.00a rkv 02/22/11 Name of the file has been changed for naming consistency
* 5.00a srt 03/06/12 Added Flushing and Invalidation of Caches to fix CRs
* 648103, 648701.
* Added V7 DDR Base Address to fix CR 649405.
* 6.00a srt 03/27/12 Changed API calls to support MCDMA driver.
* 7.00a srt 06/18/12 API calls are reverted back for backward compatibility.
* 7.02a srt 03/01/13 Updated DDR base address for IPI designs (CR 703656).
*
* </pre>
*
* ***************************************************************************
*/
/***************************** Include Files *********************************/
#include "xaxidma.h"
#include "xparameters.h"
#include "xdebug.h"
#if defined(XPAR_UARTNS550_0_BASEADDR)
#include "xuartns550_l.h" /* to use uartns550 */
#endif
#ifndef DEBUG
extern void xil_printf(const char *format, ...);
#endif
/******************** Constant Definitions **********************************/
/*********************** TEMPORARY ******************************************/
/*
* Device hardware build related constants.
*/
#define DMA_BASE_ADDR XPAR_AXIDMA_0_BASEADDR
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#ifdef XPAR_V6DDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_V6DDR_0_S_AXI_BASEADDR
#elif XPAR_S6DDR_0_S0_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_S6DDR_0_S0_AXI_BASEADDR
#elif XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR
#endif
#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR 0x01000000
#else
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000)
#endif
#define TX_BD_SPACE_BASE (MEM_BASE_ADDR)
#define TX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00000FFF)
#define RX_BD_SPACE_BASE (MEM_BASE_ADDR + 0x00001000)
#define RX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00001FFF)
#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00020000)
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00030000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x0003FFFF)
#define MAX_PKT_LEN 0x200
#define NUMBER_OF_PACKETS 0x10
#define TEST_START_VALUE 0xC
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#if defined(XPAR_UARTNS550_0_BASEADDR)
static void Uart550_Setup(void);
#endif
static int RxSetup(XAxiDma * AxiDmaInstPtr);
static int TxSetup(XAxiDma * AxiDmaInstPtr);
static int SendPackets(XAxiDma * AxiDmaInstPtr);
static int CheckData(void);
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr);
/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
XAxiDma AxiDma;
/*
* Buffer for transmit packet.
*/
u32 *Packet = (u32 *) TX_BUFFER_BASE;
static XAxiDma_Bd *LastRxBdPtr = NULL;
/*****************************************************************************/
/**
*
* Main function
*
* This function is the main entry of the tests on DMA core. It sets up
* DMA engine to be ready to receive and send packets, then a packet is
* transmitted and will be verified after it is received via the DMA loopback
* widget.
*
* @param None
*
* @return - XST_SUCCESS if test pass,
* - XST_FAILURE if test fails
*
* @note None.
*
******************************************************************************/
int main(void)
{
int Status;
XAxiDma_Config *Config;
#if defined(XPAR_UARTNS550_0_BASEADDR)
Uart550_Setup();
#endif
xil_printf("\r\n--- Entering main() --- \r\n");
Config = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!Config) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
/* Initialize DMA engine */
Status = XAxiDma_CfgInitialize(&AxiDma, Config);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}
if(!XAxiDma_HasSg(&AxiDma)) {
xil_printf("Device configured as simple mode \r\n");
return XST_FAILURE;
}
Status = TxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = RxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Send packets */
Status = SendPackets(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Check DMA transfer result */
Status = CheckDmaResult(&AxiDma);
xil_printf("Test %s\r\n",
(Status == XST_SUCCESS)? "passed":"failed");
xil_printf("--- Exiting main() --- \r\n");
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600 and data bits to 8
*
* @param None
*
* @return None
*
* @note None.
*
******************************************************************************/
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
/*****************************************************************************/
/**
*
* This function sets up RX channel of the DMA engine to be ready for packet
* reception
*
* @param AxiDmaInstPtr is the pointer to the instance of the DMA engine.
*
* @return - XST_SUCCESS if the setup is successful
* - XST_FAILURE if setup is failure
*
* @note None.
*
******************************************************************************/
static int RxSetup(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *RxRingPtr;
int Delay = 0;
int Coalesce = 1;
int Status;
XAxiDma_Bd BdTemplate;
XAxiDma_Bd *BdPtr;
XAxiDma_Bd *BdCurPtr;
u32 BdCount;
u32 FreeBdCount;
u32 RxBufferPtr;
int i;
RxRingPtr = XAxiDma_GetRxRing(&AxiDma);
/* Disable all RX interrupts before RxBD space setup */
XAxiDma_BdRingIntDisable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/* Set delay and coalescing */
XAxiDma_BdRingSetCoalesce(RxRingPtr, Coalesce, Delay);
/* Setup Rx BD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
RX_BD_SPACE_HIGH - RX_BD_SPACE_BASE + 1);
Status = XAxiDma_BdRingCreate(RxRingPtr, RX_BD_SPACE_BASE,
RX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup an all-zero BD as the template for the Rx channel.
*/
XAxiDma_BdClear(&BdTemplate);
Status = XAxiDma_BdRingClone(RxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Attach buffers to RxBD ring so we are ready to receive packets
*/
FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);
Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
BdCurPtr = BdPtr;
RxBufferPtr = RX_BUFFER_BASE;
for (i = 0; i < FreeBdCount; i++) {
Status = XAxiDma_BdSetBufAddr(BdCurPtr, RxBufferPtr);
if (Status != XST_SUCCESS) {
xil_printf("Rx set buffer addr %x on BD %x failed %d\r\n",
(unsigned int)RxBufferPtr, (unsigned int)BdCurPtr,
Status);
return XST_FAILURE;
}
Status = XAxiDma_BdSetLength(BdCurPtr, MAX_PKT_LEN,
RxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Rx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (unsigned int)BdCurPtr, Status);
return XST_FAILURE;
}
/* Receive BDs do not need to set anything for the control
* The hardware will set the SOF/EOF bits per stream status
*/
XAxiDma_BdSetCtrl(BdPtr, 0);
XAxiDma_BdSetId(BdCurPtr, RxBufferPtr);
RxBufferPtr += MAX_PKT_LEN;
if (i == (FreeBdCount - 1)) {
LastRxBdPtr = BdCurPtr;
}
BdCurPtr = XAxiDma_BdRingNext(RxRingPtr, BdCurPtr);
}
Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount, BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Start RX DMA channel */
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function sets up the TX channel of a DMA engine to be ready for packet
* transmission
*
* @param AxiDmaInstPtr is the instance pointer to the DMA engine.
*
* @return - XST_SUCCESS if the setup is successful
* - XST_FAILURE if setup is failure
*
* @note None.
*
******************************************************************************/
static int TxSetup(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_Bd BdTemplate;
int Delay = 0;
int Coalesce = 1;
int Status;
u32 BdCount;
TxRingPtr = XAxiDma_GetTxRing(&AxiDma);
/* Disable all TX interrupts before Tx BD space setup */
XAxiDma_BdRingIntDisable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/* Set TX delay and coalesce */
XAxiDma_BdRingSetCoalesce(TxRingPtr, Coalesce, Delay);
/* Setup Tx BD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
TX_BD_SPACE_HIGH - TX_BD_SPACE_BASE + 1);
Status = XAxiDma_BdRingCreate(TxRingPtr, TX_BD_SPACE_BASE,
TX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);
if (Status != XST_SUCCESS) {
xil_printf("failed create BD ring in txsetup\r\n");
return XST_FAILURE;
}
/*
* We create an all-zero BD as the template.
*/
XAxiDma_BdClear(&BdTemplate);
Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xil_printf("failed bdring clone in txsetup %d\r\n", Status);
return XST_FAILURE;
}
/* Start the TX channel */
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
xil_printf("failed start bdring txsetup %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function transmits packets non-blockingly through the DMA engine.
*
* @param AxiDmaInstPtr points to the DMA engine instance
*
* @return - XST_SUCCESS if the DMA accepts the packet successfully,
* - XST_FAILURE if failure.
*
* @note None.
*
******************************************************************************/
static int SendPackets(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
u8 *TxPacket;
u8 Value;
XAxiDma_Bd *BdPtr;
int Status;
int i;
u32 BufAddr;
XAxiDma_Bd *CurBdPtr;
/* Create pattern in the packet to transmit
*/
TxPacket = (u8 *) Packet;
Value = TEST_START_VALUE;
for(i = 0; i < MAX_PKT_LEN * NUMBER_OF_PACKETS; i ++) {
TxPacket[i] = Value;
Value = (Value + 1) & 0xFF;
}
/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((u32)TxPacket, MAX_PKT_LEN *
NUMBER_OF_PACKETS);
TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
/* Allocate BDs */
Status = XAxiDma_BdRingAlloc(TxRingPtr, NUMBER_OF_PACKETS, &BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Set up the BDs using the information of the packet to transmit */
BufAddr = (u32)Packet;
CurBdPtr = BdPtr;
for (i = 0; i < NUMBER_OF_PACKETS; i++) {
u32 CrBits = 0;
Status = XAxiDma_BdSetBufAddr(CurBdPtr, BufAddr);
if (Status != XST_SUCCESS) {
xil_printf("Tx set buffer addr %x on BD %x failed %d\r\n",
(unsigned int)BufAddr, (unsigned int)CurBdPtr, Status);
return XST_FAILURE;
}
Status = XAxiDma_BdSetLength(CurBdPtr, MAX_PKT_LEN,
TxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Tx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (unsigned int)CurBdPtr, Status);
return XST_FAILURE;
}
if (i == 0) {
CrBits |= XAXIDMA_BD_CTRL_TXSOF_MASK;
#if (XPAR_AXIDMA_0_SG_INCLUDE_STSCNTRL_STRM == 1)
/* The first BD has total transfer length set in
* the last APP word, this is for the loopback widget
*/
Status = XAxiDma_BdSetAppWord(CurBdPtr,
XAXIDMA_LAST_APPWORD,
MAX_PKT_LEN * NUMBER_OF_PACKETS);
if (Status != XST_SUCCESS) {
xil_printf("Set app word failed with %d\r\n",
Status);
}
#endif
}
if (i == (NUMBER_OF_PACKETS - 1)) {
CrBits |= XAXIDMA_BD_CTRL_TXEOF_MASK;
XAxiDma_BdSetCtrl(CurBdPtr,
XAXIDMA_BD_CTRL_TXEOF_MASK);
}
XAxiDma_BdSetCtrl(CurBdPtr, CrBits);
XAxiDma_BdSetId(CurBdPtr, BufAddr);
BufAddr += MAX_PKT_LEN;
CurBdPtr = XAxiDma_BdRingNext(TxRingPtr, CurBdPtr);
}
/* Give the BD to DMA to kick off the transmission. */
Status = XAxiDma_BdRingToHw(TxRingPtr, NUMBER_OF_PACKETS, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("to hw failed %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param None
*
* @return - XST_SUCCESS if validation is successful
* - XST_FAILURE if validation is failure.
*
* @note None.
*
******************************************************************************/
static int CheckData(void)
{
u8 *RxPacket;
int i = 0;
u8 Value;
RxPacket = (u8 *) RX_BUFFER_BASE;
Value = TEST_START_VALUE;
/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((u32)RxPacket, MAX_PKT_LEN *
NUMBER_OF_PACKETS);
for(i = 0; i < MAX_PKT_LEN * NUMBER_OF_PACKETS; i++) {
if (RxPacket[i] != Value) {
xil_printf("Data error %d: %x/%x\r\n",
i, (unsigned int)RxPacket[i], (unsigned int)Value);
return XST_FAILURE;
}
Value = (Value + 1) & 0xFF;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function delays until the DMA transaction is finished, checks data,
* and cleans up.
*
* @param AxiDmaInstPtr points to the DMA engine instance
*
* @return - XST_SUCCESS if DMA transfer is successful and data is correct
* - XST_FAILURE if failure
*
* @note None.
*
******************************************************************************/
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
XAxiDma_Bd *BdPtr;
u32 ProcessedBdCount = 0;
u32 FreeBdCount;
int Status;
TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr);
/* Wait until the TX transactions are done */
while (ProcessedBdCount < NUMBER_OF_PACKETS) {
ProcessedBdCount += XAxiDma_BdRingFromHw(TxRingPtr,
XAXIDMA_ALL_BDS, &BdPtr);
}
/* Free all processed TX BDs for future transmission */
Status = XAxiDma_BdRingFree(TxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Wait until the data has been received by the Rx channel */
ProcessedBdCount = 0;
while (ProcessedBdCount < NUMBER_OF_PACKETS) {
ProcessedBdCount += XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS, &BdPtr);
}
/* Check received data */
if (CheckData() != XST_SUCCESS) {
return XST_FAILURE;
}
/* Free all processed RX BDs for future transmission */
Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("free bd failed\r\n");
return XST_FAILURE;
}
/* Return processed BDs to RX channel so we are ready to receive new
* packets:
* - Allocate all free RX BDs
* - Pass the BDs to RX channel
*/
FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);
Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("bd alloc failed\r\n");
return XST_FAILURE;
}
Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount, BdPtr);
return Status;
}

View file

@ -0,0 +1,27 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES=*.c
INCLUDEFILES=*.h
libs:
echo "Compiling axidma"
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
make clean
include:
${CP} $(INCLUDEFILES) $(INCLUDEDIR)
clean:
rm -rf $(OUTS)

View file

@ -0,0 +1,953 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma.c
*
* This file implements DMA engine-wise initialization and control functions.
* For more information on the implementation of this driver, see xaxidma.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 4.00a rkv 02/22/11 Added support for simple DMA mode
* New API added for simple DMA mode are
* - XAxiDma_Busy
* - XAxiDma_SimpleTransfer
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA mode.
* - Changed APIs:
* * XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_SimpleTransfer(XAxiDma *InstancePtr,
* u32 BuffAddr, u32 Length,
* int Direction, int RingIndex)
* - New API:
* * XAxiDma_SelectKeyHole(XAxiDma *InstancePtr,
* int Direction, int Select)
* 7.00a srt 06/18/12 All the APIs changed in v6_00_a are reverted back for
* backward compatibility.
* 7.01a srt 10/26/12 Fixed issue with driver as it fails with IP version
* < 6.00a as the parameter C_NUM_*_CHANNELS is not
* applicable.
* 8.0 srt 01/29/14 Added support for Micro DMA Mode and Cyclic mode of
* operations.
* - New API:
* * XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr,
* int Direction, int Select)
*
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xaxidma.h"
/************************** Constant Definitions *****************************/
/* Loop counter to check reset done
*/
#define XAXIDMA_RESET_TIMEOUT 500
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int XAxiDma_Start(XAxiDma * InstancePtr);
static int XAxiDma_Started(XAxiDma * InstancePtr);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* This function initializes a DMA engine. This function must be called
* prior to using a DMA engine. Initializing a engine includes setting
* up the register base address, setting up the instance data, and ensuring the
* hardware is in a quiescent state.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
* @param Config is a pointer to an XAxiDma_Config structure. It contains
* the information about the hardware build, including base
* address,and whether status control stream (StsCntrlStrm), MM2S
* and S2MM are included in the build.
*
* @return
* - XST_SUCCESS for successful initialization
* - XST_INVALID_PARAM if pointer to the configuration structure
* is NULL
* - XST_DMA_ERROR if reset operation failed at the end of
* initialization
*
* @note We assume the hardware building tool will check and error out
* for a hardware build that has no transfer channels.
*****************************************************************************/
int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config)
{
u32 BaseAddr;
int TimeOut;
int Index;
u32 MaxTransferLen;
InstancePtr->Initialized = 0;
if(!Config) {
return XST_INVALID_PARAM;
}
BaseAddr = Config->BaseAddr;
/* Setup the instance */
memset(InstancePtr, 0, sizeof(XAxiDma));
InstancePtr->RegBase = BaseAddr;
/* Get hardware setting information from the configuration structure
*/
InstancePtr->HasMm2S = Config->HasMm2S;
InstancePtr->HasS2Mm = Config->HasS2Mm;
InstancePtr->HasSg = Config->HasSg;
InstancePtr->MicroDmaMode = Config->MicroDmaMode;
/* Get the number of channels */
InstancePtr->TxNumChannels = Config->Mm2sNumChannels;
InstancePtr->RxNumChannels = Config->S2MmNumChannels;
/* This condition is for IP version < 6.00a */
if (!InstancePtr->TxNumChannels)
InstancePtr->TxNumChannels = 1;
if (!InstancePtr->RxNumChannels)
InstancePtr->RxNumChannels = 1;
if ((InstancePtr->RxNumChannels > 1) ||
(InstancePtr->TxNumChannels > 1)) {
MaxTransferLen =
XAXIDMA_MCHAN_MAX_TRANSFER_LEN;
}
else {
MaxTransferLen =
XAXIDMA_MAX_TRANSFER_LEN;
}
/* Initialize the ring structures */
InstancePtr->TxBdRing.RunState = AXIDMA_CHANNEL_HALTED;
InstancePtr->TxBdRing.IsRxChannel = 0;
if (!InstancePtr->MicroDmaMode) {
InstancePtr->TxBdRing.MaxTransferLen = MaxTransferLen;
}
else {
/* In MicroDMA mode, Maximum length that can be transferred
* is '(Memory Data Width / 4) * Burst Size'
*/
InstancePtr->TxBdRing.MaxTransferLen =
((Config->Mm2SDataWidth / 4) *
Config->Mm2SBurstSize);
}
InstancePtr->TxBdRing.RingIndex = 0;
for (Index = 0; Index < InstancePtr->RxNumChannels; Index++) {
InstancePtr->RxBdRing[Index].RunState
= AXIDMA_CHANNEL_HALTED;
InstancePtr->RxBdRing[Index].IsRxChannel = 1;
InstancePtr->RxBdRing[Index].RingIndex = Index;
}
if (InstancePtr->HasMm2S) {
InstancePtr->TxBdRing.ChanBase =
BaseAddr + XAXIDMA_TX_OFFSET;
InstancePtr->TxBdRing.HasStsCntrlStrm =
Config->HasStsCntrlStrm;
InstancePtr->TxBdRing.HasDRE = Config->HasMm2SDRE;
InstancePtr->TxBdRing.DataWidth =
((unsigned int)Config->Mm2SDataWidth >> 3);
}
if (InstancePtr->HasS2Mm) {
for (Index = 0;
Index < InstancePtr->RxNumChannels; Index++) {
InstancePtr->RxBdRing[Index].ChanBase =
BaseAddr + XAXIDMA_RX_OFFSET;
InstancePtr->RxBdRing[Index].HasStsCntrlStrm =
Config->HasStsCntrlStrm;
InstancePtr->RxBdRing[Index].HasDRE =
Config->HasS2MmDRE;
InstancePtr->RxBdRing[Index].DataWidth =
((unsigned int)Config->S2MmDataWidth >> 3);
if (!InstancePtr->MicroDmaMode) {
InstancePtr->RxBdRing[Index].MaxTransferLen =
MaxTransferLen;
}
else {
/* In MicroDMA mode, Maximum length that can be transferred
* is '(Memory Data Width / 4) * Burst Size'
*/
InstancePtr->RxBdRing[Index].MaxTransferLen =
((Config->S2MmDataWidth / 4) *
Config->S2MmBurstSize);
}
}
}
/* Reset the engine so the hardware starts from a known state
*/
XAxiDma_Reset(InstancePtr);
/* At the initialization time, hardware should finish reset quickly
*/
TimeOut = XAXIDMA_RESET_TIMEOUT;
while (TimeOut) {
if(XAxiDma_ResetIsDone(InstancePtr)) {
break;
}
TimeOut -= 1;
}
if (!TimeOut) {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed reset in"
"initialize\r\n");
/* Need system hard reset to recover
*/
InstancePtr->Initialized = 0;
return XST_DMA_ERROR;
}
/* Initialization is successful
*/
InstancePtr->Initialized = 1;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Reset both TX and RX channels of a DMA engine.
*
* Reset one channel resets the whole AXI DMA engine.
*
* Any DMA transaction in progress will finish gracefully before engine starts
* reset. Any other transactions that have been submitted to hardware will be
* discarded by the hardware.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return None
*
* @note After the reset:
* - All interrupts are disabled.
* - Engine is halted
*
******************************************************************************/
void XAxiDma_Reset(XAxiDma * InstancePtr)
{
u32 RegBase;
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
int RingIndex;
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
/* Save the locations of current BDs both rings are working on
* before the reset so later we can resume the rings smoothly.
*/
if(XAxiDma_HasSg(InstancePtr)){
XAxiDma_BdRingSnapShotCurrBd(TxRingPtr);
for (RingIndex = 0; RingIndex < InstancePtr->RxNumChannels;
RingIndex++) {
RxRingPtr = XAxiDma_GetRxIndexRing(InstancePtr,
RingIndex);
XAxiDma_BdRingSnapShotCurrBd(RxRingPtr);
}
}
/* Reset
*/
if (InstancePtr->HasMm2S) {
RegBase = InstancePtr->RegBase + XAXIDMA_TX_OFFSET;
}
else {
RegBase = InstancePtr->RegBase + XAXIDMA_RX_OFFSET;
}
XAxiDma_WriteReg(RegBase, XAXIDMA_CR_OFFSET, XAXIDMA_CR_RESET_MASK);
/* Set TX/RX Channel state */
if (InstancePtr->HasMm2S) {
TxRingPtr->RunState = AXIDMA_CHANNEL_HALTED;
}
for (RingIndex = 0; RingIndex < InstancePtr->RxNumChannels;
RingIndex++) {
RxRingPtr = XAxiDma_GetRxIndexRing(InstancePtr, RingIndex);
if (InstancePtr->HasS2Mm) {
RxRingPtr->RunState = AXIDMA_CHANNEL_HALTED;
}
}
}
/*****************************************************************************/
/**
*
* Check whether reset is done
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - 1 if reset is done.
* - 0 if reset is not done
*
* @note None
*
******************************************************************************/
int XAxiDma_ResetIsDone(XAxiDma * InstancePtr)
{
u32 RegisterValue;
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
RxRingPtr = XAxiDma_GetRxRing(InstancePtr);
/* Check transmit channel
*/
if (InstancePtr->HasMm2S) {
RegisterValue = XAxiDma_ReadReg(TxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET);
/* Reset is done when the reset bit is low
*/
if(RegisterValue & XAXIDMA_CR_RESET_MASK) {
return 0;
}
}
/* Check receive channel
*/
if (InstancePtr->HasS2Mm) {
RegisterValue = XAxiDma_ReadReg(RxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET);
/* Reset is done when the reset bit is low
*/
if(RegisterValue & XAXIDMA_CR_RESET_MASK) {
return 0;
}
}
return 1;
}
/*****************************************************************************/
/*
* Start the DMA engine.
*
* Start a halted engine. Processing of BDs is not started.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - XST_SUCCESS for success
* - XST_NOT_SGDMA if the driver instance has not been initialized
* - XST_DMA_ERROR if starting the hardware channel fails
*
* @note None
*
*****************************************************************************/
static int XAxiDma_Start(XAxiDma * InstancePtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
int Status;
int RingIndex = 0;
if (!InstancePtr->Initialized) {
xdbg_printf(XDBG_DEBUG_ERROR, "Start: Driver not initialized "
"%d\r\n", InstancePtr->Initialized);
return XST_NOT_SGDMA;
}
if (InstancePtr->HasMm2S) {
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
if (TxRingPtr->RunState == AXIDMA_CHANNEL_HALTED) {
/* Start the channel
*/
if(XAxiDma_HasSg(InstancePtr)) {
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Start hw tx channel failed %d\r\n",
Status);
return XST_DMA_ERROR;
}
}
else {
XAxiDma_WriteReg(TxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(TxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET)
| XAXIDMA_CR_RUNSTOP_MASK);
}
TxRingPtr->RunState = AXIDMA_CHANNEL_NOT_HALTED;
}
}
if (InstancePtr->HasS2Mm) {
for (RingIndex = 0; RingIndex < InstancePtr->RxNumChannels;
RingIndex++) {
RxRingPtr = XAxiDma_GetRxIndexRing(InstancePtr,
RingIndex);
if (RxRingPtr->RunState != AXIDMA_CHANNEL_HALTED) {
return XST_SUCCESS;
}
/* Start the channel
*/
if(XAxiDma_HasSg(InstancePtr)) {
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Start hw tx channel failed %d\r\n",
Status);
return XST_DMA_ERROR;
}
}
else {
XAxiDma_WriteReg(RxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(RxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET) |
XAXIDMA_CR_RUNSTOP_MASK);
}
RxRingPtr->RunState = AXIDMA_CHANNEL_NOT_HALTED;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Pause DMA transactions on both channels.
*
* If the engine is running and doing transfers, this function does not stop
* the DMA transactions immediately, because then hardware will throw away
* our previously queued transfers. All submitted transfers will finish.
* Transfers submitted after this function will not start until
* XAxiDma_BdRingStart() or XAxiDma_Resume() is called.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - XST_SUCCESS if successful
* - XST_NOT_SGDMA, if the driver instance is not initialized
*
* @note None
*
*****************************************************************************/
int XAxiDma_Pause(XAxiDma * InstancePtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
int RingIndex = 0;
if (!InstancePtr->Initialized) {
xdbg_printf(XDBG_DEBUG_ERROR, "Pause: Driver not initialized"
" %d\r\n",InstancePtr->Initialized);
return XST_NOT_SGDMA;
}
if (InstancePtr->HasMm2S) {
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
/* If channel is halted, then we do not need to do anything
*/
if(!XAxiDma_HasSg(InstancePtr)) {
XAxiDma_WriteReg(TxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(TxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET)
& ~XAXIDMA_CR_RUNSTOP_MASK);
}
TxRingPtr->RunState = AXIDMA_CHANNEL_HALTED;
}
if (InstancePtr->HasS2Mm) {
for (RingIndex = 0; RingIndex < InstancePtr->RxNumChannels;
RingIndex++) {
RxRingPtr = XAxiDma_GetRxIndexRing(InstancePtr, RingIndex);
/* If channel is halted, then we do not need to do anything
*/
if(!XAxiDma_HasSg(InstancePtr) && !RingIndex) {
XAxiDma_WriteReg(RxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(RxRingPtr->ChanBase,
XAXIDMA_CR_OFFSET)
& ~XAXIDMA_CR_RUNSTOP_MASK);
}
RxRingPtr->RunState = AXIDMA_CHANNEL_HALTED;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Resume DMA transactions on both channels.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - XST_SUCCESS for success
* - XST_NOT_SGDMA if the driver instance has not been initialized
* - XST_DMA_ERROR if one of the channels fails to start
*
* @note None
*
*****************************************************************************/
int XAxiDma_Resume(XAxiDma * InstancePtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
int Status;
int RingIndex = 0;
if (!InstancePtr->Initialized) {
xdbg_printf(XDBG_DEBUG_ERROR, "Resume: Driver not initialized"
" %d\r\n",InstancePtr->Initialized);
return XST_NOT_SGDMA;
}
/* If the DMA engine is not running, start it. Start may fail.
*/
if (!XAxiDma_Started(InstancePtr)) {
Status = XAxiDma_Start(InstancePtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Resume: failed to start"
" engine %d\r\n", Status);
return Status;
}
}
/* Mark the state to be not halted
*/
if (InstancePtr->HasMm2S) {
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
if(XAxiDma_HasSg(InstancePtr)) {
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Resume: failed"
" to start tx ring %d\r\n", Status);
return XST_DMA_ERROR;
}
}
TxRingPtr->RunState = AXIDMA_CHANNEL_NOT_HALTED;
}
if (InstancePtr->HasS2Mm) {
for (RingIndex = 0 ; RingIndex < InstancePtr->RxNumChannels;
RingIndex++) {
RxRingPtr = XAxiDma_GetRxIndexRing(InstancePtr, RingIndex);
if(XAxiDma_HasSg(InstancePtr)) {
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Resume: failed"
"to start rx ring %d\r\n", Status);
return XST_DMA_ERROR;
}
}
RxRingPtr->RunState = AXIDMA_CHANNEL_NOT_HALTED;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
* Check whether the DMA engine is started.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - 1 if engine is started
* - 0 otherwise.
*
* @note None
*
*****************************************************************************/
static int XAxiDma_Started(XAxiDma * InstancePtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
if (!InstancePtr->Initialized) {
xdbg_printf(XDBG_DEBUG_ERROR, "Started: Driver not initialized"
" %d\r\n",InstancePtr->Initialized);
return 0;
}
if (InstancePtr->HasMm2S) {
TxRingPtr = XAxiDma_GetTxRing(InstancePtr);
if (!XAxiDma_BdRingHwIsStarted(TxRingPtr)) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Started: tx ring not started\r\n");
return 0;
}
}
if (InstancePtr->HasS2Mm) {
RxRingPtr = XAxiDma_GetRxRing(InstancePtr);
if (!XAxiDma_BdRingHwIsStarted(RxRingPtr)) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Started: rx ring not started\r\n");
return 0;
}
}
return 1;
}
/*****************************************************************************/
/**
* This function checks whether specified DMA channel is busy
*
* @param InstancePtr is the driver instance we are working on
*
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
*
* @return - TRUE if channel is busy
* - FALSE if channel is idle
*
* @note None.
*
*****************************************************************************/
u32 XAxiDma_Busy(XAxiDma *InstancePtr, int Direction)
{
return ((XAxiDma_ReadReg(InstancePtr->RegBase +
(XAXIDMA_RX_OFFSET * Direction),
XAXIDMA_SR_OFFSET) &
XAXIDMA_IDLE_MASK) ? FALSE : TRUE);
}
/*****************************************************************************/
/**
* This function Enable or Disable KeyHole Feature
*
* @param InstancePtr is the driver instance we are working on
*
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
* @Select Select is the option to enable (TRUE) or disable (FALSE).
*
* @return - XST_SUCCESS for success
*
* @note None.
*
*****************************************************************************/
int XAxiDma_SelectKeyHole(XAxiDma *InstancePtr, int Direction, int Select)
{
u32 Value;
Value = XAxiDma_ReadReg(InstancePtr->RegBase +
(XAXIDMA_RX_OFFSET * Direction),
XAXIDMA_CR_OFFSET);
if (Select)
Value |= XAXIDMA_CR_KEYHOLE_MASK;
else
Value &= ~XAXIDMA_CR_KEYHOLE_MASK;
XAxiDma_WriteReg(InstancePtr->RegBase +
(XAXIDMA_RX_OFFSET * Direction),
XAXIDMA_CR_OFFSET, Value);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function Enable or Disable Cyclic Mode Feature
*
* @param InstancePtr is the driver instance we are working on
*
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
* @Select Select is the option to enable (TRUE) or disable (FALSE).
*
* @return - XST_SUCCESS for success
*
* @note None.
*
*****************************************************************************/
int XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr, int Direction, int Select)
{
u32 Value;
Value = XAxiDma_ReadReg(InstancePtr->RegBase +
(XAXIDMA_RX_OFFSET * Direction),
XAXIDMA_CR_OFFSET);
if (Select)
Value |= XAXIDMA_CR_CYCLIC_MASK;
else
Value &= ~XAXIDMA_CR_CYCLIC_MASK;
XAxiDma_WriteReg(InstancePtr->RegBase +
(XAXIDMA_RX_OFFSET * Direction),
XAXIDMA_CR_OFFSET, Value);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function does one simple transfer submission
*
* It checks in the following sequence:
* - if engine is busy, cannot submit
* - if engine is in SG mode , cannot submit
*
* @param InstancePtr is the pointer to the driver instance
* @param BuffAddr is the address of the source/destination buffer
* @param Length is the length of the transfer
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
* @return
* - XST_SUCCESS for success of submission
* - XST_FAILURE for submission failure, maybe caused by:
* Another simple transfer is still going
* - XST_INVALID_PARAM if:Length out of valid range [1:8M]
* Or, address not aligned when DRE is not built in
*
* @note This function is used only when system is configured as
* Simple mode.
*
*****************************************************************************/
int XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, u32 BuffAddr, u32 Length,
int Direction)
{
u32 WordBits;
int RingIndex = 0;
/* If Scatter Gather is included then, cannot submit
*/
if (XAxiDma_HasSg(InstancePtr)) {
xdbg_printf(XDBG_DEBUG_ERROR, "Simple DMA mode is not"
" supported\r\n");
return XST_FAILURE;
}
if(Direction == XAXIDMA_DMA_TO_DEVICE){
if ((Length < 1) ||
(Length > InstancePtr->TxBdRing.MaxTransferLen)) {
return XST_INVALID_PARAM;
}
if (!InstancePtr->HasMm2S) {
xdbg_printf(XDBG_DEBUG_ERROR, "MM2S channel is not"
"supported\r\n");
return XST_FAILURE;
}
/* If the engine is doing transfer, cannot submit
*/
if(!(XAxiDma_ReadReg(InstancePtr->TxBdRing.ChanBase,
XAXIDMA_SR_OFFSET) & XAXIDMA_HALTED_MASK)) {
if (XAxiDma_Busy(InstancePtr,Direction)) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Engine is busy\r\n");
return XST_FAILURE;
}
}
if (!InstancePtr->MicroDmaMode) {
WordBits = (u32)((InstancePtr->TxBdRing.DataWidth) - 1);
}
else {
WordBits = XAXIDMA_MICROMODE_MIN_BUF_ALIGN;
}
if ((BuffAddr & WordBits)) {
if (!InstancePtr->TxBdRing.HasDRE) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Unaligned transfer without"
" DRE %x\r\n",(unsigned int)BuffAddr);
return XST_INVALID_PARAM;
}
}
XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase,
XAXIDMA_SRCADDR_OFFSET, BuffAddr);
XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(
InstancePtr->TxBdRing.ChanBase,
XAXIDMA_CR_OFFSET)| XAXIDMA_CR_RUNSTOP_MASK);
/* Writing to the BTT register starts the transfer
*/
XAxiDma_WriteReg(InstancePtr->TxBdRing.ChanBase,
XAXIDMA_BUFFLEN_OFFSET, Length);
}
else if(Direction == XAXIDMA_DEVICE_TO_DMA){
if ((Length < 1) ||
(Length >
InstancePtr->RxBdRing[RingIndex].MaxTransferLen)) {
return XST_INVALID_PARAM;
}
if (!InstancePtr->HasS2Mm) {
xdbg_printf(XDBG_DEBUG_ERROR, "S2MM channel is not"
" supported\r\n");
return XST_FAILURE;
}
if(!(XAxiDma_ReadReg(InstancePtr->RxBdRing[RingIndex].ChanBase,
XAXIDMA_SR_OFFSET) & XAXIDMA_HALTED_MASK)) {
if (XAxiDma_Busy(InstancePtr,Direction)) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Engine is busy\r\n");
return XST_FAILURE;
}
}
if (!InstancePtr->MicroDmaMode) {
WordBits =
(u32)((InstancePtr->RxBdRing[RingIndex].DataWidth) - 1);
}
else {
WordBits = XAXIDMA_MICROMODE_MIN_BUF_ALIGN;
}
if ((BuffAddr & WordBits)) {
if (!InstancePtr->RxBdRing[RingIndex].HasDRE) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Unaligned transfer without"
" DRE %x\r\n", (unsigned int)BuffAddr);
return XST_INVALID_PARAM;
}
}
XAxiDma_WriteReg(InstancePtr->RxBdRing[RingIndex].ChanBase,
XAXIDMA_DESTADDR_OFFSET, BuffAddr);
XAxiDma_WriteReg(InstancePtr->RxBdRing[RingIndex].ChanBase,
XAXIDMA_CR_OFFSET,
XAxiDma_ReadReg(InstancePtr->RxBdRing[RingIndex].ChanBase,
XAXIDMA_CR_OFFSET)| XAXIDMA_CR_RUNSTOP_MASK);
/* Writing to the BTT register starts the transfer
*/
XAxiDma_WriteReg(InstancePtr->RxBdRing[RingIndex].ChanBase,
XAXIDMA_BUFFLEN_OFFSET, Length);
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,727 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma.h
*
* This is the driver API for the AXI DMA engine.
*
* For a full description of DMA features, please see the hardware spec. This
* driver supports the following features:
*
* - Scatter-Gather DMA (SGDMA)
* - Simple DMA
* - Interrupts
* - Programmable interrupt coalescing for SGDMA
* - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA
* engine
*
* <b>Simple DMA</b>
*
* Simple DMA allows the application to define a single transaction between DMA
* and Device. It has two channels: one from the DMA to Device and the other
* from Device to DMA. Application has to set the buffer address and
* length fields to initiate the transfer in respective channel.
*
* <b>Transactions</b>
*
* The object used to describe a transaction is referred to as a Buffer
* Descriptor (BD). Buffer descriptors are allocated in the user application.
* The user application needs to set buffer address, transfer length, and
* control information for this transfer. The control information includes
* SOF and EOF. Definition of those masks are in xaxidma_hw.h
*
* <b>Scatter-Gather DMA</b>
*
* SGDMA allows the application to define a list of transactions in memory which
* the hardware will process without further application intervention. During
* this time, the application is free to continue adding more work to keep the
* Hardware busy.
*
* User can check for the completion of transactions through polling the
* hardware, or interrupts.
*
* SGDMA processes whole packets. A packet is defined as a series of
* data bytes that represent a message. SGDMA allows a packet of data to be
* broken up into one or more transactions. For example, take an Ethernet IP
* packet which consists of a 14 byte header followed by a 1 or more bytes of
* payload. With SGDMA, the application may point a BD to the header and another
* BD to the payload, then transfer them as a single message. This strategy can
* make a TCP/IP stack more efficient by allowing it to keep packet header and
* data in different memory regions instead of assembling packets into
* contiguous blocks of memory.
*
* <b>BD Ring Management</b>
*
* BD rings are shared by the software and the hardware.
*
* The hardware expects BDs to be setup as a linked list. The DMA hardware walks
* through the list by following the next pointer field of a completed BD.
* The hardware stops processing when the just completed BD is the same as the
* BD specified in the Tail Ptr register in the hardware.
*
* The last BD in the ring is linked to the first BD in the ring.
*
* All BD management are done inside the driver. The user application should not
* directly modify the BD fields. Modifications to the BD fields should always
* go through the specific API functions.
*
* Within the ring, the driver maintains four groups of BDs. Each group consists
* of 0 or more adjacent BDs:
*
* - Free: The BDs that can be allocated by the application with
* XAxiDma_BdRingAlloc().
*
* - Pre-process: The BDs that have been allocated with
* XAxiDma_BdRingAlloc(). These BDs are under application control. The
* application modifies these BDs through driver API to prepare them
* for DMA transactions.
*
* - Hardware: The BDs that have been enqueued to hardware with
* XAxiDma_BdRingToHw(). These BDs are under hardware control and may be in a
* state of awaiting hardware processing, in process, or processed by
* hardware. It is considered an error for the application to change BDs
* while they are in this group. Doing so can cause data corruption and lead
* to system instability.
*
* - Post-process: The BDs that have been processed by hardware and have
* been extracted from the Hardware group with XAxiDma_BdRingFromHw().
* These BDs are under application control. The application can check the
* transfer status of these BDs. The application use XAxiDma_BdRingFree()
* to put them into the Free group.
*
* BDs are expected to transition in the following way for continuous
* DMA transfers:
* <pre>
*
* XAxiDma_BdRingAlloc() XAxiDma_BdRingToHw()
* Free ------------------------> Pre-process ----------------------> Hardware
* |
* /|\ |
* | XAxiDma_BdRingFree() XAxiDma_BdRingFromHw() |
* +--------------------------- Post-process <----------------------+
*
* </pre>
*
* When a DMA transfer is to be cancelled before enqueuing to hardware,
* application can return the requested BDs to the Free group using
* XAxiDma_BdRingUnAlloc(), as shown below:
* <pre>
*
* XAxiDma_BdRingUnAlloc()
* Free <----------------------- Pre-process
*
* </pre>
*
* The API provides functions for BD list traversal:
* - XAxiDma_BdRingNext()
* - XAxiDma_BdRingPrev()
*
* These functions should be used with care as they do not understand where
* one group ends and another begins.
*
* <b>SGDMA Descriptor Ring Creation</b>
*
* BD ring is created using XAxiDma_BdRingCreate(). The memory for the BD ring
* is allocated by the application, and it has to be contiguous. Physical
* address is required to setup the BD ring.
*
* The applicaiton can use XAxiDma_BdRingMemCalc() to find out the amount of
* memory needed for a certain number of BDs. XAxiDma_BdRingCntCalc() can be
* used to find out how many BDs can be allocated for certain amount of memory.
*
* A helper function, XAxiDma_BdRingClone(), can speed up the BD ring setup if
* the BDs have same types of controls, for example, SOF and EOF. After
* using the XAxiDma_BdRingClone(), the application only needs to setup the
* buffer address and transfer length. Note that certain BDs in one packet,
* for example, the first BD and the last BD, may need to setup special
* control information.
*
* <b>Descriptor Ring State Machine</b>
*
* There are two states of the BD ring:
*
* - HALTED (H), where hardware is not running
*
* - NOT HALTED (NH), where hardware is running
*
* The following diagram shows the state transition for the DMA engine:
*
* <pre>
* _____ XAxiDma_StartBdRingHw(), or XAxiDma_BdRingStart(), ______
* | | or XAxiDma_Resume() | |
* | H |----------------------------------------------------->| NH |
* | |<-----------------------------------------------------| |
* ----- XAxiDma_Pause() or XAxiDma_Reset() ------
* </pre>
*
* <b>Interrupt Coalescing</b>
*
* SGDMA provides control over the frequency of interrupts through interrupt
* coalescing. The DMA engine provides two ways to tune the interrupt
* coalescing:
*
* - The packet threshold counter. Interrupt will fire once the
* programmable number of packets have been processed by the engine.
*
* - The packet delay timer counter. Interrupt will fire once the
* programmable amount of time has passed after processing the last packet,
* and no new packets to process. Note that the interrupt will only fire if
* at least one packet has been processed.
*
* <b> Interrupt </b>
*
* Interrupts are handled by the user application. Each DMA channel has its own
* interrupt ID. The driver provides APIs to enable/disable interrupt,
* and tune the interrupt frequency regarding to packet processing frequency.
*
* <b> Software Initialization </b>
*
*
* To use the Simple mode DMA engine for transfers, the following setup is
* required:
*
* - DMA Initialization using XAxiDma_CfgInitialize() function. This step
* initializes a driver instance for the given DMA engine and resets the
* engine.
*
* - Enable interrupts if chosen to use interrupt mode. The application is
* responsible for setting up the interrupt system, which includes providing
* and connecting interrupt handlers and call back functions, before
* enabling the interrupts.
*
* - Set the buffer address and length field in respective channels to start
* the DMA transfer
*
* To use the SG mode DMA engine for transfers, the following setup are
* required:
*
* - DMA Initialization using XAxiDma_CfgInitialize() function. This step
* initializes a driver instance for the given DMA engine and resets the
* engine.
*
* - BD Ring creation. A BD ring is needed per DMA channel and can be built by
* calling XAxiDma_BdRingCreate().
*
* - Enable interrupts if chose to use interrupt mode. The application is
* responsible for setting up the interrupt system, which includes providing
* and connecting interrupt handlers and call back functions, before
* enabling the interrupts.
*
* - Start a DMA transfer: Call XAxiDma_BdRingStart() to start a transfer for
* the first time or after a reset, and XAxiDma_BdRingToHw() if the channel
* is already started. Calling XAxiDma_BdRingToHw() when a DMA channel is not
* running will not put the BDs to the hardware, and the BDs will be processed
* later when the DMA channel is started through XAxiDma_BdRingStart().
*
* <b> How to start DMA transactions </b>
*
* The user application uses XAxiDma_BdRingToHw() to submit BDs to the hardware
* to start DMA transfers.
*
* For both channels, if the DMA engine is currently stopped (using
* XAxiDma_Pause()), the newly added BDs will be accepted but not processed
* until the DMA engine is started, using XAxiDma_BdRingStart(), or resumed,
* using XAxiDma_Resume().
*
* <b> Software Post-Processing on completed DMA transactions </b>
*
* If the interrupt system has been set up and the interrupts are enabled,
* a DMA channels notifies the software about the completion of a transfer
* through interrupts. Otherwise, the user application can poll for
* completions of the BDs, using XAxiDma_BdRingFromHw() or
* XAxiDma_BdHwCompleted().
*
* - Once BDs are finished by a channel, the application first needs to fetch
* them from the channel using XAxiDma_BdRingFromHw().
*
* - On the TX side, the application now could free the data buffers attached to
* those BDs as the data in the buffers has been transmitted.
*
* - On the RX side, the application now could use the received data in the
* buffers attached to those BDs.
*
* - For both channels, completed BDs need to be put back to the Free group
* using XAxiDma_BdRingFree(), so they can be used for future transactions.
*
* - On the RX side, it is the application's responsibility to have BDs ready
* to receive data at any time. Otherwise, the RX channel refuses to
* accept any data if it has no RX BDs.
*
* <b> Examples </b>
*
* We provide five examples to show how to use the driver API:
* - One for SG interrupt mode (xaxidma_example_sg_intr.c), multiple BD/packets transfer
* - One for SG polling mode (xaxidma_example_sg_poll.c), single BD transfer.
* - One for SG polling mode (xaxidma_poll_multi_pkts.c), multiple BD/packets transfer
* - One for simple polling mode (xaxidma_example_simple_poll.c)
* - One for simple Interrupt mode (xaxidma_example_simple_intr.c)
*
* <b> Address Translation </b>
*
* All buffer addresses and BD addresses for the hardware are physical
* addresses. The user application is responsible to provide physical buffer
* address for the BD upon BD ring creation. The user application accesses BD
* through its virtual addess. The driver maintains the address translation
* between the physical and virtual address for BDs.
*
* <b> Cache Coherency </b>
*
* This driver expects all application buffers attached to BDs to be in cache
* coherent memory. If cache is used in the system, buffers for transmit MUST
* be flushed from the cache before passing the associated BD to this driver.
* Buffers for receive MUST be invalidated before accessing the data.
*
* <b> Alignment </b>
*
* For BDs:
*
* Minimum alignment is defined by the constant XAXIDMA_BD_MINIMUM_ALIGNMENT.
* This is the smallest alignment allowed by both hardware and software for them
* to properly work.
*
* If the descriptor ring is to be placed in cached memory, alignment also MUST
* be at least the processor's cache-line size. Otherwise, system instability
* occurs. For alignment larger than the cache line size, multiple cache line
* size alignment is required.
*
* Aside from the initial creation of the descriptor ring (see
* XAxiDma_BdRingCreate()), there are no other run-time checks for proper
* alignment of BDs.
*
* For application data buffers:
*
* Application data buffers may reside on any alignment if DRE is built into the
* hardware. Otherwise, application data buffer must be word-aligned. The word
* is defined by XPAR_AXIDMA_0_M_AXIS_MM2S_TDATA_WIDTH for transmit and
* XPAR_AXIDMA_0_S_AXIS_S2MM_TDATA_WIDTH for receive.
*
* For scatter gather transfers that have more than one BDs in the chain of BDs,
* Each BD transfer length must be multiple of word too. Otherwise, internal
* error happens in the hardware.
*
* <b> Error Handling </b>
*
* The DMA engine will halt on all error conditions. It requires the software
* to do a reset before it can start process new transfer requests.
*
* <b> Restart After Stopping </b>
*
* After the DMA engine has been stopped (through reset or reset after an error)
* the software keeps track of the current BD pointer when reset happens, and
* processing of BDs can be resumed through XAxiDma_BdRingStart().
*
* <b> Limitations </b>
*
* This driver does not have any mechanisms for mutual exclusion. It is up to
* the application to provide this protection.
*
* <b> Hardware Defaults & Exclusive Use </b>
*
* After the initialization or reset, the DMA engine is in the following
* default mode:
* - All interrupts are disabled.
*
* - Interrupt coalescing counter is 1.
*
* - The DMA engine is not running (halted). Each DMA channel is started
* separately, using XAxiDma_StartBdRingHw() if no BDs are setup for transfer
* yet, or XAxiDma_BdRingStart() otherwise.
*
* The driver has exclusive use of the registers and BDs. All accesses to the
* registers and BDs should go through the driver interface.
*
* <b> Debug Print </b>
*
* To see the debug print for the driver, please put "-DDEBUG" as the extra
* compiler flags in software platform settings. Also comment out the line in
* xdebug.h: "#undef DEBUG".
*
* <b>Changes From v1.00a</b>
*
* . We have changes return type for XAxiDma_BdSetBufAddr() from void to int
* . We added XAxiDma_LookupConfig() so that user does not need to look for the
* hardware settings anymore.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 4.00a rkv 02/22/11 Added support for simple DMA mode
* New API added for simple DMA mode are
* - XAxiDma_Busy
* - XAxiDma_SimpleTransfer
* New Macros added for simple DMA mode are
* - XAxiDma_HasSg
* - XAxiDma_IntrEnable
* - XAxiDma_IntrGetEnabled
* - XAxiDma_IntrDisable
* - XAxiDma_IntrGetIrq
* - XAxiDma_IntrAckIrq
* 5.00a srt 08/25/11 Added support for memory barrier and modified
* Cache Macros to have a common API for Microblaze
* and Zynq.
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA mode.
* - Changed APIs:
* * XAxiDma_GetRxRing(InstancePtr, RingIndex)
* * XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_SimpleTransfer(XAxiDma *InstancePtr,
* u32 BuffAddr, u32 Length,
* int Direction, int RingIndex)
* * XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
* int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
* * XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr,
* u32 LenBytes, u32 LengthMask)
* * XAxiDma_BdGetActualLength(BdPtr, LengthMask)
* * XAxiDma_BdGetLength(BdPtr, LengthMask)
* - New APIs
* * XAxiDma_SelectKeyHole(XAxiDma *InstancePtr,
* int Direction, int Select)
* * XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* 7.00a srt 06/18/12 All the APIs changed in v6_00_a are reverted back for
* backward compatibility.
* - New API:
* XAxiDma_GetRxIndexRing(InstancePtr, RingIndex)
* 7.01a srt 10/26/12 - Fixed issue with driver as it fails with IP version
* < 6.00a as the parameter C_NUM_*_CHANNELS is not
* applicable.
* - Changed the logic of MCDMA BD fields Set APIs, to
* clear the field first and then set it.
* 7.02a srt 01/23/13 Replaced *_TDATA_WIDTH parameters to *_DATA_WIDTH
* (CR 691867)
* Updated DDR base address for IPI designs (CR 703656).
* 8.0 adk 19/12/13 Updated as per the New Tcl API's
* srt 01/29/14 Added support for Micro DMA Mode and cyclic mode of
* operations.
* - New APIs:
* * XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr,
* int Direction, int Select)
* * XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd*, u32)
*
* </pre>
*
******************************************************************************/
#ifndef XAXIDMA_H_ /* prevent circular inclusions */
#define XAXIDMA_H_
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xaxidma_bdring.h"
#ifdef __MICROBLAZE__
#include "xenv.h"
#else
#include <string.h>
#include "xil_cache.h"
#endif
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/**
* The XAxiDma driver instance data. An instance must be allocated for each DMA
* engine in use.
*/
typedef struct XAxiDma {
u32 RegBase; /* Virtual base address of DMA engine */
int HasMm2S; /* Has transmit channel */
int HasS2Mm; /* Has receive channel */
int Initialized; /* Driver has been initialized */
int HasSg;
XAxiDma_BdRing TxBdRing; /* BD container management for TX channel */
XAxiDma_BdRing RxBdRing[16]; /* BD container management for RX channel */
int TxNumChannels;
int RxNumChannels;
int MicroDmaMode;
} XAxiDma;
/**
* The configuration structure for AXI DMA engine
*
* This structure passes the hardware building information to the driver
*/
typedef struct {
u32 DeviceId;
u32 BaseAddr;
int HasStsCntrlStrm;
int HasMm2S;
int HasMm2SDRE;
int Mm2SDataWidth;
int HasS2Mm;
int HasS2MmDRE;
int S2MmDataWidth;
int HasSg;
int Mm2sNumChannels;
int S2MmNumChannels;
int Mm2SBurstSize;
int S2MmBurstSize;
int MicroDmaMode;
} XAxiDma_Config;
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
* Get Transmit (Tx) Ring ptr
*
* Warning: This has a different API than the LLDMA driver. It now returns
* the pointer to the BD ring.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return Pointer to the Tx Ring
*
* @note C-style signature:
* XAxiDma_BdRing * XAxiDma_GetTxRing(XAxiDma * InstancePtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_GetTxRing(InstancePtr) \
(&((InstancePtr)->TxBdRing))
/*****************************************************************************/
/**
* Get Receive (Rx) Ring ptr
*
* Warning: This has a different API than the LLDMA driver. It now returns
* the pointer to the BD ring.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return Pointer to the Rx Ring
*
* @note
* C-style signature:
* XAxiDma_BdRing * XAxiDma_GetRxRing(XAxiDma * InstancePtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_GetRxRing(InstancePtr) \
(&((InstancePtr)->RxBdRing[0]))
/*****************************************************************************/
/**
* Get Receive (Rx) Ring ptr of a Index
*
* Warning: This has a different API than the LLDMA driver. It now returns
* the pointer to the BD ring.
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
* @param RingIndex is the channel Index.
*
* @return Pointer to the Rx Ring
*
* @note
* C-style signature:
* XAxiDma_BdRing * XAxiDma_GetRxIndexRing(XAxiDma * InstancePtr,
int RingIndex)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_GetRxIndexRing(InstancePtr, RingIndex) \
(&((InstancePtr)->RxBdRing[RingIndex]))
/*****************************************************************************/
/**
* This function checks whether system is configured as Simple or
* Scatter Gather mode
*
* @param InstancePtr is a pointer to the DMA engine instance to be
* worked on.
*
* @return
* - TRUE if configured as SG mode
* - FALSE if configured as simple mode
*
* @note None
*
*****************************************************************************/
#define XAxiDma_HasSg(InstancePtr) ((InstancePtr)->HasSg) ? TRUE : FALSE
/*****************************************************************************/
/**
* This function enables interrupts specified by the Mask in specified
* direction, Interrupts that are not in the mask are not affected.
*
* @param InstancePtr is the driver instance we are working on
* @param Mask is the mask for the interrupts to be enabled
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
* @return None
*
* @note None
*
*****************************************************************************/
#define XAxiDma_IntrEnable(InstancePtr, Mask, Direction) \
XAxiDma_WriteReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET, \
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET)) \
| (Mask & XAXIDMA_IRQ_ALL_MASK))
/*****************************************************************************/
/**
* This function gets the mask for the interrupts that are currently enabled
*
* @param InstancePtr is the driver instance we are working on
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
*
* @return The bit mask for the interrupts that are currently enabled
*
* @note None
*
*****************************************************************************/
#define XAxiDma_IntrGetEnabled(InstancePtr, Direction) \
XAxiDma_ReadReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET) &\
XAXIDMA_IRQ_ALL_MASK)
/*****************************************************************************/
/**
* This function disables interrupts specified by the Mask. Interrupts that
* are not in the mask are not affected.
*
* @param InstancePtr is the driver instance we are working on
* @param Mask is the mask for the interrupts to be disabled
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
* @return None
*
* @note None
*
*****************************************************************************/
#define XAxiDma_IntrDisable(InstancePtr, Mask, Direction) \
XAxiDma_WriteReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET, \
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET)) \
& ~(Mask & XAXIDMA_IRQ_ALL_MASK))
/*****************************************************************************/
/**
* This function gets the interrupts that are asserted.
*
* @param InstancePtr is the driver instance we are working on
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
*
* @return The bit mask for the interrupts asserted.
*
* @note None
*
*****************************************************************************/
#define XAxiDma_IntrGetIrq(InstancePtr, Direction) \
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_SR_OFFSET) &\
XAXIDMA_IRQ_ALL_MASK)
/*****************************************************************************/
/**
* This function acknowledges the interrupts that are specified in Mask
*
* @param InstancePtr is the driver instance we are working on
* @param Mask is the mask for the interrupts to be acknowledge
* @param Direction is DMA transfer direction, valid values are
* - XAXIDMA_DMA_TO_DEVICE.
* - XAXIDMA_DEVICE_TO_DMA.
*
* @return None
*
* @note None.
*
*****************************************************************************/
#define XAxiDma_IntrAckIrq(InstancePtr, Mask, Direction) \
XAxiDma_WriteReg((InstancePtr)->RegBase + \
(XAXIDMA_RX_OFFSET * Direction), XAXIDMA_SR_OFFSET, \
(Mask) & XAXIDMA_IRQ_ALL_MASK)
/************************** Function Prototypes ******************************/
/*
* Initialization and control functions in xaxidma.c
*/
XAxiDma_Config *XAxiDma_LookupConfig(u32 DeviceId);
int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config);
void XAxiDma_Reset(XAxiDma * InstancePtr);
int XAxiDma_ResetIsDone(XAxiDma * InstancePtr);
int XAxiDma_Pause(XAxiDma * InstancePtr);
int XAxiDma_Resume(XAxiDma * InstancePtr);
u32 XAxiDma_Busy(XAxiDma *InstancePtr,int Direction);
int XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, u32 BuffAddr, u32 Length,
int Direction);
int XAxiDma_SelectKeyHole(XAxiDma *InstancePtr, int Direction, int Select);
int XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr, int Direction, int Select);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,339 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_bd.c
*
* Buffer descriptor (BD) management API implementation.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA.
* - Changed APIs
* * XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr,
* u32 LenBytes, u32 LengthMask)
* * XAxiDma_BdGetActualLength(BdPtr, LengthMask)
* * XAxiDma_BdGetLength(BdPtr, LengthMask)
* 8.0 srt 01/29/14 Added support for Micro DMA Mode:
* - New API
* XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd*, u32)
*
* </pre>
*
*****************************************************************************/
#include "xaxidma_bd.h"
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
* Set the length field for the given BD.
*
* Length has to be non-zero and less than LengthMask.
*
* For TX channels, the value passed in should be the number of bytes to
* transmit from the TX buffer associated with the given BD.
*
* For RX channels, the value passed in should be the size of the RX buffer
* associated with the given BD in bytes. This is to notify the RX channel
* the capability of the RX buffer to avoid buffer overflow.
*
* The actual receive length can be equal or smaller than the specified length.
* The actual transfer length will be updated by the hardware in the
* XAXIDMA_BD_STS_OFFSET word in the BD.
*
* @param BdPtr is the BD to operate on.
* @param LenBytes is the requested transfer length
* @param LengthMask is the maximum transfer length
*
* @returns
* - XST_SUCCESS for success
* - XST_INVALID_PARAM for invalid BD length
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
int XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr, u32 LenBytes, u32 LengthMask)
{
if (LenBytes <= 0 || (LenBytes > LengthMask)) {
xdbg_printf(XDBG_DEBUG_ERROR, "invalid length %d\n",
(int)LenBytes);
return XST_INVALID_PARAM;
}
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET,
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) & \
~LengthMask)) | LenBytes);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Set the BD's buffer address.
*
* @param BdPtr is the BD to operate on
* @param Addr is the address to set
*
* @return
* - XST_SUCCESS if buffer address set successfully
* - XST_INVALID_PARAM if hardware has no DRE and address is not
* aligned
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
int XAxiDma_BdSetBufAddr(XAxiDma_Bd* BdPtr, u32 Addr)
{
u32 HasDRE;
u8 WordLen;
HasDRE = XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_DRE_OFFSET);
WordLen = HasDRE & XAXIDMA_BD_WORDLEN_MASK;
if (Addr & (WordLen - 1)) {
if ((HasDRE & XAXIDMA_BD_HAS_DRE_MASK) == 0) {
xil_printf("Error set buf addr %x with %x and %x,"
" %x\r\n",Addr, HasDRE, (WordLen - 1),
Addr & (WordLen - 1));
return XST_INVALID_PARAM;
}
}
XAxiDma_BdWrite(BdPtr, XAXIDMA_BD_BUFA_OFFSET, Addr);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Set the BD's buffer address when configured for Micro Mode. The buffer
* address should be 4K aligned.
*
* @param BdPtr is the BD to operate on
* @param Addr is the address to set
*
* @return
* - XST_SUCCESS if buffer address set successfully
* - XST_INVALID_PARAM if hardware has no DRE and address is not
* aligned
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
int XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd* BdPtr, u32 Addr)
{
if (Addr & XAXIDMA_MICROMODE_MIN_BUF_ALIGN) {
xil_printf("Error set buf addr %x and %x,"
" %x\r\n", Addr, XAXIDMA_MICROMODE_MIN_BUF_ALIGN,
Addr & XAXIDMA_MICROMODE_MIN_BUF_ALIGN);
return XST_INVALID_PARAM;
}
XAxiDma_BdWrite(BdPtr, XAXIDMA_BD_BUFA_OFFSET, Addr);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Set the APP word at the specified APP word offset for a BD.
*
* @param BdPtr is the BD to operate on.
* @param Offset is the offset inside the APP word, it is valid from
* 0 to 4
* @param Word is the value to set
*
* @returns
* - XST_SUCCESS for success
* - XST_INVALID_PARAM under following error conditions:
* 1) StsCntrlStrm is not built in hardware
* 2) Offset is not in valid range
*
* @note
* If the hardware build has C_SG_USE_STSAPP_LENGTH set to 1,
* then the last APP word, XAXIDMA_LAST_APPWORD, must have
* non-zero value when AND with 0x7FFFFF. Not doing so will cause
* the hardware to stall.
* This function can be used only when DMA is in SG mode
*
*****************************************************************************/
int XAxiDma_BdSetAppWord(XAxiDma_Bd* BdPtr, int Offset, u32 Word)
{
if (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_STSCNTRL_OFFSET) == 0) {
xdbg_printf(XDBG_DEBUG_ERROR, "BdRingSetAppWord: no sts cntrl"
"stream in hardware build, cannot set app word\r\n");
return XST_INVALID_PARAM;
}
if ((Offset < 0) || (Offset > XAXIDMA_LAST_APPWORD)) {
xdbg_printf(XDBG_DEBUG_ERROR, "BdRingSetAppWord: invalid"
"offset %d",Offset);
return XST_INVALID_PARAM;
}
XAxiDma_BdWrite(BdPtr, XAXIDMA_BD_USR0_OFFSET + Offset * 4, Word);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* Get the APP word at the specified APP word offset for a BD.
*
* @param BdPtr is the BD to operate on.
* @param Offset is the offset inside the APP word, it is valid from
* 0 to 4
* @param Valid is to tell the caller whether parameters are valid
*
* @returns
* The APP word. Passed in parameter Valid holds 0 for failure,
* and 1 for success.
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
u32 XAxiDma_BdGetAppWord(XAxiDma_Bd* BdPtr, int Offset, int *Valid)
{
*Valid = 0;
if (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_STSCNTRL_OFFSET) == 0) {
xdbg_printf(XDBG_DEBUG_ERROR, "BdRingGetAppWord: no sts cntrl "
"stream in hardware build, no app word available\r\n");
return (u32)0;
}
if((Offset < 0) || (Offset > XAXIDMA_LAST_APPWORD)) {
xdbg_printf(XDBG_DEBUG_ERROR, "BdRingGetAppWord: invalid"
" offset %d", Offset);
return (u32)0;
}
*Valid = 1;
return XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR0_OFFSET + Offset * 4);
}
/*****************************************************************************/
/**
* Set the control bits for a BD.
*
* @param BdPtr is the BD to operate on.
* @param Data is the bit value to set
*
* @return None
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
void XAxiDma_BdSetCtrl(XAxiDma_Bd* BdPtr, u32 Data)
{
u32 RegValue = XAxiDma_BdRead(BdPtr, XAXIDMA_BD_CTRL_LEN_OFFSET);
RegValue &= ~XAXIDMA_BD_CTRL_ALL_MASK;
RegValue |= (Data & XAXIDMA_BD_CTRL_ALL_MASK);
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET, RegValue);
return;
}
/*****************************************************************************/
/**
* Dump the fields of a BD.
*
* @param BdPtr is the BD to operate on.
*
* @return None
*
* @note This function can be used only when DMA is in SG mode
*
*****************************************************************************/
void XAxiDma_DumpBd(XAxiDma_Bd* BdPtr)
{
xil_printf("Dump BD %x:\r\n", (unsigned int)BdPtr);
xil_printf("\tNext Bd Ptr: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_NDESC_OFFSET));
xil_printf("\tBuff addr: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_BUFA_OFFSET));
xil_printf("\tMCDMA Fields: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_MCCTL_OFFSET));
xil_printf("\tVSIZE_STRIDE: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr,
XAXIDMA_BD_STRIDE_VSIZE_OFFSET));
xil_printf("\tContrl len: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_CTRL_LEN_OFFSET));
xil_printf("\tStatus: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_STS_OFFSET));
xil_printf("\tAPP 0: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR0_OFFSET));
xil_printf("\tAPP 1: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR1_OFFSET));
xil_printf("\tAPP 2: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR2_OFFSET));
xil_printf("\tAPP 3: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR3_OFFSET));
xil_printf("\tAPP 4: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR4_OFFSET));
xil_printf("\tSW ID: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_ID_OFFSET));
xil_printf("\tStsCtrl: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr,
XAXIDMA_BD_HAS_STSCNTRL_OFFSET));
xil_printf("\tDRE: %x\r\n",
(unsigned int)XAxiDma_BdRead(BdPtr, XAXIDMA_BD_HAS_DRE_OFFSET));
xil_printf("\r\n");
}

View file

@ -0,0 +1,671 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_bd.h
*
* Buffer descriptor (BD) management API.
*
* <b> Buffer Descriptors </b>
*
* A BD defines a DMA transaction (see "Transaction" section in xaxidma.h).
* All accesses to a BD go through this set of API.
*
* The XAxiDma_Bd structure defines a BD. The first XAXIDMA_BD_HW_NUM_BYTES
* are shared between hardware and software.
*
* <b> Actual Transfer Length </b>
*
* The actual transfer length for receive could be smaller than the requested
* transfer length. The hardware sets the actual transfer length in the
* completed BD. The API to retrieve the actual transfer length is
* XAxiDma_GetActualLength().
*
* <b> User IP words </b>
*
* There are 5 user IP words in each BD.
*
* If hardware does not have the StsCntrl stream built in, then these words
* are not usable. Retrieving these words get a NULL pointer and setting
* these words results an error.
*
* <b> Performance </b>
*
* BDs are typically in a non-cached memory space. Reducing the number of
* I/O operations to BDs can improve overall performance of the DMA channel.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 5.00a srt 08/25/11 Changed Cache Macros to have a common API for Zynq
* and Microblaze.
* 6.00a srt 01/24/12 Added APIs to support Multi-Channel DMA:
* XAxiDma_BdSetTId()
* XAxiDma_BdGetTId()
* XAxiDma_BdSetTDest()
* XAxiDma_BdGetTDest()
* XAxiDma_BdSetTUser()
* XAxiDma_BdGetTUser()
* XAxiDma_BdSetARCache()
* XAxiDma_BdGetARCache()
* XAxiDma_BdSetARUser()
* XAxiDma_BdGetARUser()
* XAxiDma_BdSetStride()
* XAxiDma_BdGetStride()
* XAxiDma_BdSetVSize()
* XAxiDma_BdGetVSize()
* - Changed APIs
* XAxiDma_BdGetActualLength(BdPtr, LengthMask)
* XAxiDma_BdGetLength(BdPtr, LengthMask)
* XAxiDma_BdSetLength(XAxiDma_Bd* BdPtr,
* u32 LenBytes, u32 LengthMask)
* 7.01a srt 10/26/12 Changed the logic of MCDMA BD fields Set APIs, to
* clear the field first and set it.
* 8.0 srt 01/29/14 Added support for Micro DMA Mode.
*
* </pre>
*****************************************************************************/
#ifndef XAXIDMA_BD_H_ /* To prevent circular inclusions */
#define XAXIDMA_BD_H_
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xaxidma_hw.h"
#include "xstatus.h"
#include "xdebug.h"
#include "xil_cache.h"
#ifdef __MICROBLAZE__
#include "xenv.h"
#else
#include <string.h>
#endif
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/**
* The XAxiDma_Bd is the type for a buffer descriptor (BD).
*/
typedef u32 XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS];
/***************** Macros (Inline Functions) Definitions *********************/
/******************************************************************************
* Define methods to flush and invalidate cache for BDs should they be
* located in cached memory.
*****************************************************************************/
#define XAXIDMA_CACHE_FLUSH(BdPtr) \
Xil_DCacheFlushRange((unsigned int)(BdPtr), XAXIDMA_BD_HW_NUM_BYTES)
#define XAXIDMA_CACHE_INVALIDATE(BdPtr) \
Xil_DCacheInvalidateRange((unsigned int)(BdPtr), XAXIDMA_BD_HW_NUM_BYTES)
/*****************************************************************************/
/**
*
* Read the given Buffer Descriptor word.
*
* @param BaseAddress is the base address of the BD to read
* @param Offset is the word offset to be read
*
* @return The 32-bit value of the field
*
* @note
* C-style signature:
* u32 XAxiDma_BdRead(u32 BaseAddress, u32 Offset)
*
******************************************************************************/
#define XAxiDma_BdRead(BaseAddress, Offset) \
(*(u32*)((u32)(BaseAddress) + (u32)(Offset)))
/*****************************************************************************/
/**
*
* Write the given Buffer Descriptor word.
*
* @param BaseAddress is the base address of the BD to write
* @param Offset is the word offset to be written
* @param Data is the 32-bit value to write to the field
*
* @return None.
*
* @note
* C-style signature:
* void XAxiDma_BdWrite(u32 BaseAddress, u32 RegOffset, u32 Data)
*
******************************************************************************/
#define XAxiDma_BdWrite(BaseAddress, Offset, Data) \
(*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
/*****************************************************************************/
/**
* Zero out BD specific fields. BD fields that are for the BD ring or for the
* system hardware build information are not touched.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdClear(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdClear(BdPtr) \
memset((void *)(((u32)(BdPtr)) + XAXIDMA_BD_START_CLEAR), 0, \
XAXIDMA_BD_BYTES_TO_CLEAR)
/*****************************************************************************/
/**
* Get the control bits for the BD
*
* @param BdPtr is the BD to operate on
*
* @return The bit mask for the control of the BD
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetCtrl(BdPtr) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) \
& XAXIDMA_BD_CTRL_ALL_MASK)
/*****************************************************************************/
/**
* Retrieve the status of a BD
*
* @param BdPtr is the BD to operate on
*
* @return Word at offset XAXIDMA_BD_DMASR_OFFSET. Use XAXIDMA_BD_STS_***
* values defined in xaxidma_hw.h to interpret the returned value
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetSts(BdPtr) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \
XAXIDMA_BD_STS_ALL_MASK)
/*****************************************************************************/
/**
* Retrieve the length field value from the given BD. The returned value is
* the same as what was written with XAxiDma_BdSetLength(). Note that in the
* this value does not reflect the real length of received data.
* See the comments of XAxiDma_BdSetLength() for more details. To obtain the
* actual transfer length, use XAxiDma_BdGetActualLength().
*
* @param BdPtr is the BD to operate on.
* @param LengthMask is the Maximum Transfer Length.
*
* @return The length value set in the BD.
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetLength(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetLength(BdPtr, LengthMask) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) & \
LengthMask)
/*****************************************************************************/
/**
* Set the ID field of the given BD. The ID is an arbitrary piece of data the
* application can associate with a specific BD.
*
* @param BdPtr is the BD to operate on
* @param Id is a 32 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetId(XAxiDma_Bd* BdPtr, void Id)
*
*****************************************************************************/
#define XAxiDma_BdSetId(BdPtr, Id) \
(XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_ID_OFFSET, (u32)(Id)))
/*****************************************************************************/
/**
* Retrieve the ID field of the given BD previously set with XAxiDma_BdSetId.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetId(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetId(BdPtr) (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_ID_OFFSET))
/*****************************************************************************/
/**
* Get the BD's buffer address
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetBufAddr(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetBufAddr(BdPtr) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_BUFA_OFFSET))
/*****************************************************************************/
/**
* Check whether a BD has completed in hardware. This BD has been submitted
* to hardware. The application can use this function to poll for the
* completion of the BD.
*
* This function may not work if the BD is in cached memory.
*
* @param BdPtr is the BD to check on
*
* @return
* - 0 if not complete
* - XAXIDMA_BD_STS_COMPLETE_MASK if completed, may contain
* XAXIDMA_BD_STS_*_ERR_MASK bits.
*
* @note
* C-style signature:
* int XAxiDma_BdHwCompleted(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdHwCompleted(BdPtr) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \
XAXIDMA_BD_STS_COMPLETE_MASK)
/*****************************************************************************/
/**
* Get the actual transfer length of a BD. The BD has completed in hw.
*
* This function may not work if the BD is in cached memory.
*
* @param BdPtr is the BD to check on
* @param LengthMask is the Maximum Transfer Length.
*
* @return None
*
* @note
* C-style signature:
* int XAxiDma_BdGetActualLength(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetActualLength(BdPtr, LengthMask) \
(XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \
LengthMask)
/*****************************************************************************/
/**
* Set the TID field of the TX BD.
* Provides a stream identifier and can be used to differentiate between
* multiple streams of data that are being transferred across the same
* interface.
*
* @param BdPtr is the BD to operate on
* @param TId is a 8 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetTId(XAxiDma_Bd* BdPtr, void TId)
*
*****************************************************************************/
#define XAxiDma_BdSetTId(BdPtr, TId) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \
~XAXIDMA_BD_TID_FIELD_MASK); \
val |= ((u32)(TId) << XAXIDMA_BD_TID_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the TID field of the RX BD previously set with XAxiDma_BdSetTId.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetTId(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetTId(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \
XAXIDMA_BD_TID_FIELD_MASK)
/*****************************************************************************/
/**
* Set the TDEST field of the TX BD.
* Provides coarse routing information for the data stream.
*
* @param BdPtr is the BD to operate on
* @param TDest is a 8 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetTDest(XAxiDma_Bd* BdPtr, void TDest)
*
*****************************************************************************/
#define XAxiDma_BdSetTDest(BdPtr, TDest) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \
~XAXIDMA_BD_TDEST_FIELD_MASK); \
val |= ((u32)(TDest) << XAXIDMA_BD_TDEST_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the TDest field of the RX BD previously set with i
* XAxiDma_BdSetTDest.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetTDest(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetTDest(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \
XAXIDMA_BD_TDEST_FIELD_MASK)
/*****************************************************************************/
/**
* Set the TUSER field of the TX BD.
* User defined sideband signaling.
*
* @param BdPtr is the BD to operate on
* @param TUser is a 8 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetTUser(XAxiDma_Bd* BdPtr, void TUser)
*
*****************************************************************************/
#define XAxiDma_BdSetTUser(BdPtr, TUser) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \
~XAXIDMA_BD_TUSER_FIELD_MASK); \
val |= ((u32)(TUser) << XAXIDMA_BD_TUSER_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the TUSER field of the RX BD previously set with
* XAxiDma_BdSetTUser.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetTUser(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetTUser(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \
XAXIDMA_BD_TUSER_FIELD_MASK)
/*****************************************************************************/
/**
* Set the ARCACHE field of the given BD.
* This signal provides additional information about the cacheable
* characteristics of the transfer.
*
* @param BdPtr is the BD to operate on
* @param ARCache is a 8 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetARCache(XAxiDma_Bd* BdPtr, void ARCache)
*
*****************************************************************************/
#define XAxiDma_BdSetARCache(BdPtr, ARCache) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \
~XAXIDMA_BD_ARCACHE_FIELD_MASK); \
val |= ((u32)(ARCache) << XAXIDMA_BD_ARCACHE_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the ARCACHE field of the given BD previously set with
* XAxiDma_BdSetARCache.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetARCache(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetARCache(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET)) & \
XAXIDMA_BD_ARCACHE_FIELD_MASK)
/*****************************************************************************/
/**
* Set the ARUSER field of the given BD.
* Sideband signals used for user defined information.
*
* @param BdPtr is the BD to operate on
* @param ARUser is a 8 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetARUser(XAxiDma_Bd* BdPtr, void ARUser)
*
*****************************************************************************/
#define XAxiDma_BdSetARUser(BdPtr, ARUser) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \
~XAXIDMA_BD_ARUSER_FIELD_MASK); \
val |= ((u32)(ARUser) << XAXIDMA_BD_ARUSER_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the ARUSER field of the given BD previously set with
* XAxiDma_BdSetARUser.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetARUser(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetARUser(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET)) & \
XAXIDMA_BD_ARUSER_FIELD_MASK)
/*****************************************************************************/
/**
* Set the STRIDE field of the given BD.
* It is the address distance between the first address of successive
* horizontal reads.
*
* @param BdPtr is the BD to operate on
* @param Stride is a 32 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetStride(XAxiDma_Bd* BdPtr, void Stride)
*
*****************************************************************************/
#define XAxiDma_BdSetStride(BdPtr, Stride) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET) & \
~XAXIDMA_BD_STRIDE_FIELD_MASK); \
val |= ((u32)(Stride) << XAXIDMA_BD_STRIDE_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the STRIDE field of the given BD previously set with
* XAxiDma_BdSetStride.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetStride(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetStride(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET)) & \
XAXIDMA_BD_STRIDE_FIELD_MASK)
/*****************************************************************************/
/**
* Set the VSIZE field of the given BD.
* Number of horizontal lines for strided access.
*
* @param BdPtr is the BD to operate on
* @param VSize is a 32 bit quantity to set in the BD
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdSetVSize(XAxiDma_Bd* BdPtr, void VSize)
*
*****************************************************************************/
#define XAxiDma_BdSetVSize(BdPtr, VSize) \
{ \
u32 val; \
val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET) & \
~XAXIDMA_BD_VSIZE_FIELD_MASK); \
val |= ((u32)(VSize) << XAXIDMA_BD_VSIZE_FIELD_SHIFT); \
XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET, val); \
}
/*****************************************************************************/
/**
* Retrieve the STRIDE field of the given BD previously set with
* XAxiDma_BdSetVSize.
*
* @param BdPtr is the BD to operate on
*
* @return None
*
* @note
* C-style signature:
* u32 XAxiDma_BdGetVSize(XAxiDma_Bd* BdPtr)
*
*****************************************************************************/
#define XAxiDma_BdGetVSize(BdPtr) \
((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET)) & \
XAXIDMA_BD_VSIZE_FIELD_MASK)
/*****************************************************************************/
/************************** Function Prototypes ******************************/
int XAxiDma_BdSetLength(XAxiDma_Bd* BdPtr, u32 LenBytes, u32 LengthMask);
int XAxiDma_BdSetBufAddr(XAxiDma_Bd* BdPtr, u32 Addr);
int XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd* BdPtr, u32 Addr);
int XAxiDma_BdSetAppWord(XAxiDma_Bd * BdPtr, int Offset, u32 Word);
u32 XAxiDma_BdGetAppWord(XAxiDma_Bd * BdPtr, int Offset, int *Valid);
void XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data);
/* Debug utility
*/
void XAxiDma_DumpBd(XAxiDma_Bd* BdPtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,522 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_bdring.h
*
* This file contains DMA channel related structure and constant definition
* as well as function prototypes. Each DMA channel is managed by a Buffer
* Descriptor ring, and XAxiDma_BdRing is chosen as the symbol prefix used in
* this file. See xaxidma.h for more information on how a BD ring is managed.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA.
* - New API
* * XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* - Changed APIs
* * XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
* int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
* * XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* 7.00a srt 06/18/12 All the APIs changed in v6_00_a are reverted back for
* backward compatibility.
*
*
* </pre>
*
******************************************************************************/
#ifndef XAXIDMA_BDRING_H_ /* prevent circular inclusions */
#define XAXIDMA_BDRING_H_
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xaxidma_bd.h"
/************************** Constant Definitions *****************************/
/* State of a DMA channel
*/
#define AXIDMA_CHANNEL_NOT_HALTED 1
#define AXIDMA_CHANNEL_HALTED 2
/* Argument constant to simplify argument setting
*/
#define XAXIDMA_NO_CHANGE 0xFFFFFFFF
#define XAXIDMA_ALL_BDS 0x0FFFFFFF /* 268 Million */
/**************************** Type Definitions *******************************/
/** Container structure for descriptor storage control. If address translation
* is enabled, then all addresses and pointers excluding FirstBdPhysAddr are
* expressed in terms of the virtual address.
*/
typedef struct {
u32 ChanBase; /**< physical base address*/
int IsRxChannel; /**< Is this a receive channel */
volatile int RunState; /**< Whether channel is running */
int HasStsCntrlStrm; /**< Whether has stscntrl stream */
int HasDRE;
int DataWidth;
u32 MaxTransferLen;
u32 FirstBdPhysAddr; /**< Physical address of 1st BD in list */
u32 FirstBdAddr; /**< Virtual address of 1st BD in list */
u32 LastBdAddr; /**< Virtual address of last BD in the list */
u32 Length; /**< Total size of ring in bytes */
u32 Separation; /**< Number of bytes between the starting
address of adjacent BDs */
XAxiDma_Bd *FreeHead; /**< First BD in the free group */
XAxiDma_Bd *PreHead; /**< First BD in the pre-work group */
XAxiDma_Bd *HwHead; /**< First BD in the work group */
XAxiDma_Bd *HwTail; /**< Last BD in the work group */
XAxiDma_Bd *PostHead; /**< First BD in the post-work group */
XAxiDma_Bd *BdaRestart; /**< BD to load when channel is started */
int FreeCnt; /**< Number of allocatable BDs in free group */
int PreCnt; /**< Number of BDs in pre-work group */
int HwCnt; /**< Number of BDs in work group */
int PostCnt; /**< Number of BDs in post-work group */
int AllCnt; /**< Total Number of BDs for channel */
int RingIndex; /**< Ring Index */
} XAxiDma_BdRing;
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
* Use this macro at initialization time to determine how many BDs will fit
* within the given memory constraints.
*
* The results of this macro can be provided to XAxiDma_BdRingCreate().
*
* @param Alignment specifies what byte alignment the BDs must fall
* on and must be a power of 2 to get an accurate calculation
* (32, 64, 126,...)
* @param Bytes is the number of bytes to be used to store BDs.
*
* @return Number of BDs that can fit in the given memory area
*
* @note
* C-style signature:
* int XAxiDma_BdRingCntCalc(u32 Alignment, u32 Bytes)
* This function is used only when system is configured as SG mode
*
******************************************************************************/
#define XAxiDma_BdRingCntCalc(Alignment, Bytes) \
(int)((Bytes)/((sizeof(XAxiDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
/*****************************************************************************/
/**
* Use this macro at initialization time to determine how many bytes of memory
* are required to contain a given number of BDs at a given alignment.
*
* @param Alignment specifies what byte alignment the BDs must fall on.
* This parameter must be a power of 2 to get an accurate
* calculation (32, 64,128,...)
* @param NumBd is the number of BDs to calculate memory size
* requirements
*
* @return The number of bytes of memory required to create a BD list
* with the given memory constraints.
*
* @note
* C-style signature:
* int XAxiDma_BdRingMemCalc(u32 Alignment, u32 NumBd)
* This function is used only when system is configured as SG mode
*
******************************************************************************/
#define XAxiDma_BdRingMemCalc(Alignment, NumBd) \
(int)((sizeof(XAxiDma_Bd)+((Alignment)-1)) & ~((Alignment)-1))*(NumBd)
/****************************************************************************/
/**
* Return the total number of BDs allocated by this channel with
* XAxiDma_BdRingCreate().
*
* @param RingPtr is the BD ring to operate on.
*
* @return The total number of BDs allocated for this channel.
*
* @note
* C-style signature:
* int XAxiDma_BdRingGetCnt(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
/****************************************************************************/
/**
* Return the number of BDs allocatable with XAxiDma_BdRingAlloc() for pre-
* processing.
*
* @param RingPtr is the BD ring to operate on.
*
* @return The number of BDs currently allocatable.
*
* @note
* C-style signature:
* int XAxiDma_BdRingGetFreeCnt(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
/****************************************************************************/
/**
* Snap shot the latest BD a BD ring is processing.
*
* @param RingPtr is the BD ring to operate on.
*
* @return None
*
* @note
* C-style signature:
* void XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingSnapShotCurrBd(RingPtr) \
{ \
if (!RingPtr->IsRxChannel) { \
(RingPtr)->BdaRestart = \
(XAxiDma_Bd *)XAxiDma_ReadReg((RingPtr)->ChanBase, \
XAXIDMA_CDESC_OFFSET); \
} else { \
if (!RingPtr->RingIndex) { \
(RingPtr)->BdaRestart = \
(XAxiDma_Bd *)XAxiDma_ReadReg( \
(RingPtr)->ChanBase, \
XAXIDMA_CDESC_OFFSET); \
} else { \
(RingPtr)->BdaRestart = \
(XAxiDma_Bd *)XAxiDma_ReadReg( \
(RingPtr)->ChanBase, \
(XAXIDMA_RX_CDESC0_OFFSET + \
(RingPtr->RingIndex - 1) * \
XAXIDMA_RX_NDESC_OFFSET)); \
} \
} \
}
/****************************************************************************/
/**
* Get the BD a BD ring is processing.
*
* @param RingPtr is the BD ring to operate on.
*
* @return The current BD that the BD ring is working on
*
* @note
* C-style signature:
* XAxiDma_Bd * XAxiDma_BdRingGetCurrBd(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetCurrBd(RingPtr) \
(XAxiDma_Bd *)XAxiDma_ReadReg((RingPtr)->ChanBase, \
XAXIDMA_CDESC_OFFSET) \
/****************************************************************************/
/**
* Return the next BD in the ring.
*
* @param RingPtr is the BD ring to operate on.
* @param BdPtr is the current BD.
*
* @return The next BD in the ring relative to the BdPtr parameter.
*
* @note
* C-style signature:
* XAxiDma_Bd *XAxiDma_BdRingNext(XAxiDma_BdRing* RingPtr,
* XAxiDma_Bd *BdPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingNext(RingPtr, BdPtr) \
(((u32)(BdPtr) >= (RingPtr)->LastBdAddr) ? \
(XAxiDma_Bd*)(RingPtr)->FirstBdAddr : \
(XAxiDma_Bd*)((u32)(BdPtr) + (RingPtr)->Separation))
/****************************************************************************/
/**
* Return the previous BD in the ring.
*
* @param RingPtr is the DMA channel to operate on.
* @param BdPtr is the current BD.
*
* @return The previous BD in the ring relative to the BdPtr parameter.
*
* @note
* C-style signature:
* XAxiDma_Bd *XAxiDma_BdRingPrev(XAxiDma_BdRing* RingPtr,
* XAxiDma_Bd *BdPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingPrev(RingPtr, BdPtr) \
(((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ? \
(XAxiDma_Bd*)(RingPtr)->LastBdAddr : \
(XAxiDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
/****************************************************************************/
/**
* Retrieve the contents of the channel status register
*
* @param RingPtr is the channel instance to operate on.
*
* @return Current contents of status register
*
* @note
* C-style signature:
* u32 XAxiDma_BdRingGetSr(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetSr(RingPtr) \
XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET)
/****************************************************************************/
/**
* Get error bits of a DMA channel
*
* @param RingPtr is the channel instance to operate on.
*
* @return Rrror bits in the status register, they should be interpreted
* with XAXIDMA_ERR_*_MASK defined in xaxidma_hw.h
*
* @note
* C-style signature:
* u32 XAxiDma_BdRingGetError(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetError(RingPtr) \
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
& XAXIDMA_ERR_ALL_MASK)
/****************************************************************************/
/**
* Check whether a DMA channel is started, meaning the channel is not halted.
*
* @param RingPtr is the channel instance to operate on.
*
* @return
* - 1 if channel is started
* - 0 otherwise
*
* @note
* C-style signature:
* int XAxiDma_BdRingHwIsStarted(XAxiDma_BdRing* RingPtr)
*
*****************************************************************************/
#define XAxiDma_BdRingHwIsStarted(RingPtr) \
((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
& XAXIDMA_HALTED_MASK) ? FALSE : TRUE)
/****************************************************************************/
/**
* Check if the current DMA channel is busy with a DMA operation.
*
* @param RingPtr is the channel instance to operate on.
*
* @return
* - 1 if the DMA is busy.
* - 0 otherwise
*
* @note
* C-style signature:
* int XAxiDma_BdRingBusy(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingBusy(RingPtr) \
(XAxiDma_BdRingHwIsStarted(RingPtr) && \
((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
& XAXIDMA_IDLE_MASK) ? FALSE : TRUE))
/****************************************************************************/
/**
* Set interrupt enable bits for a channel. This operation will modify the
* XAXIDMA_CR_OFFSET register.
*
* @param RingPtr is the channel instance to operate on.
* @param Mask consists of the interrupt signals to enable.Bits not
* specified in the mask are not affected.
*
* @note
* C-style signature:
* void XAxiDma_BdRingIntEnable(XAxiDma_BdRing* RingPtr, u32 Mask)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingIntEnable(RingPtr, Mask) \
(XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \
XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \
| ((Mask) & XAXIDMA_IRQ_ALL_MASK)))
/****************************************************************************/
/**
* Get enabled interrupts of a channel. It is in XAXIDMA_CR_OFFSET register.
*
* @param RingPtr is the channel instance to operate on.
* @return Enabled interrupts of a channel. Use XAXIDMA_IRQ_* defined in
* xaxidma_hw.h to interpret this returned value.
*
* @note
* C-style signature:
* u32 XAxiDma_BdRingIntGetEnabled(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingIntGetEnabled(RingPtr) \
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \
& XAXIDMA_IRQ_ALL_MASK)
/****************************************************************************/
/**
* Clear interrupt enable bits for a channel. It modifies the
* XAXIDMA_CR_OFFSET register.
*
* @param RingPtr is the channel instance to operate on.
* @param Mask consists of the interrupt signals to disable.Bits not
* specified in the Mask are not affected.
*
* @note
* C-style signature:
* void XAxiDma_BdRingIntDisable(XAxiDma_BdRing* RingPtr,
* u32 Mask)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingIntDisable(RingPtr, Mask) \
(XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \
XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) & \
~((Mask) & XAXIDMA_IRQ_ALL_MASK)))
/****************************************************************************/
/**
* Retrieve the contents of the channel's IRQ register XAXIDMA_SR_OFFSET. This
* operation can be used to see which interrupts are pending.
*
* @param RingPtr is the channel instance to operate on.
*
* @return Current contents of the IRQ_OFFSET register. Use
* XAXIDMA_IRQ_*** values defined in xaxidma_hw.h to interpret
* the returned value.
*
* @note
* C-style signature:
* u32 XAxiDma_BdRingGetIrq(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingGetIrq(RingPtr) \
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
& XAXIDMA_IRQ_ALL_MASK)
/****************************************************************************/
/**
* Acknowledge asserted interrupts. It modifies XAXIDMA_SR_OFFSET register.
* A mask bit set for an unasserted interrupt has no effect.
*
* @param RingPtr is the channel instance to operate on.
* @param Mask are the interrupt signals to acknowledge
*
* @note
* C-style signature:
* void XAxiDma_BdRingAckIrq(XAxiDma_BdRing* RingPtr)
* This function is used only when system is configured as SG mode
*
*****************************************************************************/
#define XAxiDma_BdRingAckIrq(RingPtr, Mask) \
XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET,\
(Mask) & XAXIDMA_IRQ_ALL_MASK)
/************************* Function Prototypes ******************************/
/*
* Descriptor ring functions xaxidma_bdring.c
*/
int XAxiDma_StartBdRingHw(XAxiDma_BdRing* RingPtr);
int XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing* RingPtr);
int XAxiDma_BdRingCreate(XAxiDma_BdRing * RingPtr, u32 PhysAddr,
u32 VirtAddr, u32 Alignment, int BdCount);
int XAxiDma_BdRingClone(XAxiDma_BdRing * RingPtr, XAxiDma_Bd * SrcBdPtr);
int XAxiDma_BdRingAlloc(XAxiDma_BdRing * RingPtr, int NumBd,
XAxiDma_Bd ** BdSetPtr);
int XAxiDma_BdRingUnAlloc(XAxiDma_BdRing * RingPtr, int NumBd,
XAxiDma_Bd * BdSetPtr);
int XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr, int NumBd,
XAxiDma_Bd * BdSetPtr);
int XAxiDma_BdRingFromHw(XAxiDma_BdRing * RingPtr, int BdLimit,
XAxiDma_Bd ** BdSetPtr);
int XAxiDma_BdRingFree(XAxiDma_BdRing * RingPtr, int NumBd,
XAxiDma_Bd * BdSetPtr);
int XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr);
int XAxiDma_BdRingSetCoalesce(XAxiDma_BdRing * RingPtr, u32 Counter, u32 Timer);
void XAxiDma_BdRingGetCoalesce(XAxiDma_BdRing * RingPtr,
u32 *CounterPtr, u32 *TimerPtr);
/* The following functions are for debug only
*/
int XAxiDma_BdRingCheck(XAxiDma_BdRing * RingPtr);
void XAxiDma_BdRingDumpRegs(XAxiDma_BdRing *RingPtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,83 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_g.c
*
* Provide a template for user to define their own hardware settings.
*
* If using XPS, then XPS will automatically generate this file.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 08/16/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 4.00a rkv 02/22/11 Added support for simple DMA mode
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA mode
* 7.02a srt 01/23/13 Replaced *_TDATA_WIDTH parameters to *_DATA_WIDTH
* (CR 691867)
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xaxidma.h"
/************************** Constant Definitions *****************************/
#define XPAR_AXIDMA_0_INCLUDE_SG 0
XAxiDma_Config XAxiDma_ConfigTable[] =
{
{
XPAR_AXIDMA_0_DEVICE_ID,
XPAR_AXIDMA_0_BASEADDR,
XPAR_AXIDMA_0_SG_INCLUDE_STSCNTRL_STRM,
XPAR_AXIDMA_0_INCLUDE_MM2S,
XPAR_AXIDMA_0_INCLUDE_MM2S_DRE,
XPAR_AXIDMA_0_M_AXI_MM2S_DATA_WIDTH,
XPAR_AXIDMA_0_INCLUDE_S2MM,
XPAR_AXIDMA_0_INCLUDE_S2MM_DRE,
XPAR_AXIDMA_0_M_AXI_S2MM_DATA_WIDTH,
XPAR_AXIDMA_0_INCLUDE_SG,
XPAR_AXIDMA_0_NUM_MM2S_CHANNELS,
XPAR_AXIDMA_0_NUM_S2MM_CHANNELS
}
};

View file

@ -0,0 +1,331 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_hw.h
*
* Hardware definition file. It defines the register interface and Buffer
* Descriptor (BD) definitions.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 4.00a rkv 02/22/11 Added support for simple DMA mode
* 6.00a srt 01/24/12 Added support for Multi-Channel DMA mode
* 8.0 srt 01/29/14 Added support for Micro DMA Mode and Cyclic mode of
* operations.
*
* </pre>
*
*****************************************************************************/
#ifndef XAXIDMA_HW_H_ /* prevent circular inclusions */
#define XAXIDMA_HW_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xil_types.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name DMA Transfer Direction
* @{
*/
#define XAXIDMA_DMA_TO_DEVICE 0x00
#define XAXIDMA_DEVICE_TO_DMA 0x01
/** @name Buffer Descriptor Alignment
* @{
*/
#define XAXIDMA_BD_MINIMUM_ALIGNMENT 0x40 /**< Minimum byte alignment
requirement for descriptors to
satisfy both hardware/software
needs */
/*@}*/
/** @name Micro DMA Buffer Address Alignment
* @{
*/
#define XAXIDMA_MICROMODE_MIN_BUF_ALIGN 0xFFF /**< Minimum byte alignment
requirement for buffer address
in Micro DMA mode */
/*@}*/
/** @name Maximum transfer length
* This is determined by hardware
* @{
*/
#define XAXIDMA_MAX_TRANSFER_LEN 0x7FFFFF /* Max length hw supports */
#define XAXIDMA_MCHAN_MAX_TRANSFER_LEN 0x00FFFF /* Max length MCDMA
hw supports */
/*@}*/
/* Register offset definitions. Register accesses are 32-bit.
*/
/** @name Device registers
* Register sets on TX and RX channels are identical
* @{
*/
#define XAXIDMA_TX_OFFSET 0x00000000 /**< TX channel registers base
* offset */
#define XAXIDMA_RX_OFFSET 0x00000030 /**< RX channel registers base
* offset */
/* This set of registers are applicable for both channels. Add
* XAXIDMA_TX_OFFSET to get to TX channel, and XAXIDMA_RX_OFFSET to get to RX
* channel
*/
#define XAXIDMA_CR_OFFSET 0x00000000 /**< Channel control */
#define XAXIDMA_SR_OFFSET 0x00000004 /**< Status */
#define XAXIDMA_CDESC_OFFSET 0x00000008 /**< Current descriptor pointer */
#define XAXIDMA_TDESC_OFFSET 0x00000010 /**< Tail descriptor pointer */
#define XAXIDMA_SRCADDR_OFFSET 0x00000018 /**< Simple mode source address
pointer */
#define XAXIDMA_DESTADDR_OFFSET 0x00000018 /**< Simple mode destination address pointer */
#define XAXIDMA_BUFFLEN_OFFSET 0x00000028 /**< Tail descriptor pointer */
#define XAXIDMA_SGCTL_OFFSET 0x0000002c /**< SG Control Register */
/** Multi-Channel DMA Descriptor Offsets **/
#define XAXIDMA_RX_CDESC0_OFFSET 0x00000040 /**< Rx Current Descriptor 0 */
#define XAXIDMA_RX_TDESC0_OFFSET 0x00000048 /**< Rx Tail Descriptor 0 */
#define XAXIDMA_RX_NDESC_OFFSET 0x00000020 /**< Rx Next Descriptor Offset */
/*@}*/
/** @name Bitmasks of XAXIDMA_CR_OFFSET register
* @{
*/
#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /**< Start/stop DMA channel */
#define XAXIDMA_CR_RESET_MASK 0x00000004 /**< Reset DMA engine */
#define XAXIDMA_CR_KEYHOLE_MASK 0x00000008 /**< Keyhole feature */
#define XAXIDMA_CR_CYCLIC_MASK 0x00000010 /**< Cyclic Mode */
/*@}*/
/** @name Bitmasks of XAXIDMA_SR_OFFSET register
*
* This register reports status of a DMA channel, including
* run/stop/idle state, errors, and interrupts (note that interrupt
* masks are shared with XAXIDMA_CR_OFFSET register, and are defined
* in the _IRQ_ section.
*
* The interrupt coalescing threshold value and delay counter value are
* also shared with XAXIDMA_CR_OFFSET register, and are defined in a
* later section.
* @{
*/
#define XAXIDMA_HALTED_MASK 0x00000001 /**< DMA channel halted */
#define XAXIDMA_IDLE_MASK 0x00000002 /**< DMA channel idle */
#define XAXIDMA_ERR_INTERNAL_MASK 0x00000010 /**< Datamover internal
* err */
#define XAXIDMA_ERR_SLAVE_MASK 0x00000020 /**< Datamover slave err */
#define XAXIDMA_ERR_DECODE_MASK 0x00000040 /**< Datamover decode
* err */
#define XAXIDMA_ERR_SG_INT_MASK 0x00000100 /**< SG internal err */
#define XAXIDMA_ERR_SG_SLV_MASK 0x00000200 /**< SG slave err */
#define XAXIDMA_ERR_SG_DEC_MASK 0x00000400 /**< SG decode err */
#define XAXIDMA_ERR_ALL_MASK 0x00000770 /**< All errors */
/** @name Bitmask for interrupts
* These masks are shared by XAXIDMA_CR_OFFSET register and
* XAXIDMA_SR_OFFSET register
* @{
*/
#define XAXIDMA_IRQ_IOC_MASK 0x00001000 /**< Completion intr */
#define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /**< Delay interrupt */
#define XAXIDMA_IRQ_ERROR_MASK 0x00004000 /**< Error interrupt */
#define XAXIDMA_IRQ_ALL_MASK 0x00007000 /**< All interrupts */
/*@}*/
/** @name Bitmask and shift for delay and coalesce
* These masks are shared by XAXIDMA_CR_OFFSET register and
* XAXIDMA_SR_OFFSET register
* @{
*/
#define XAXIDMA_DELAY_MASK 0xFF000000 /**< Delay timeout
* counter */
#define XAXIDMA_COALESCE_MASK 0x00FF0000 /**< Coalesce counter */
#define XAXIDMA_DELAY_SHIFT 24
#define XAXIDMA_COALESCE_SHIFT 16
/*@}*/
/* Buffer Descriptor (BD) definitions
*/
/** @name Buffer Descriptor offsets
* USR* fields are defined by higher level IP.
* setup for EMAC type devices. The first 13 words are used by hardware.
* All words after the 13rd word are for software use only.
* @{
*/
#define XAXIDMA_BD_NDESC_OFFSET 0x00 /**< Next descriptor pointer */
#define XAXIDMA_BD_BUFA_OFFSET 0x08 /**< Buffer address */
#define XAXIDMA_BD_MCCTL_OFFSET 0x10 /**< Multichannel Control Fields */
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET 0x14 /**< 2D Transfer Sizes */
#define XAXIDMA_BD_CTRL_LEN_OFFSET 0x18 /**< Control/buffer length */
#define XAXIDMA_BD_STS_OFFSET 0x1C /**< Status */
#define XAXIDMA_BD_USR0_OFFSET 0x20 /**< User IP specific word0 */
#define XAXIDMA_BD_USR1_OFFSET 0x24 /**< User IP specific word1 */
#define XAXIDMA_BD_USR2_OFFSET 0x28 /**< User IP specific word2 */
#define XAXIDMA_BD_USR3_OFFSET 0x2C /**< User IP specific word3 */
#define XAXIDMA_BD_USR4_OFFSET 0x30 /**< User IP specific word4 */
#define XAXIDMA_BD_ID_OFFSET 0x34 /**< Sw ID */
#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET 0x38 /**< Whether has stscntrl strm */
#define XAXIDMA_BD_HAS_DRE_OFFSET 0x3C /**< Whether has DRE */
#define XAXIDMA_BD_HAS_DRE_MASK 0xF00 /**< Whether has DRE mask */
#define XAXIDMA_BD_WORDLEN_MASK 0xFF /**< Whether has DRE mask */
#define XAXIDMA_BD_HAS_DRE_SHIFT 8 /**< Whether has DRE shift */
#define XAXIDMA_BD_WORDLEN_SHIFT 0 /**< Whether has DRE shift */
#define XAXIDMA_BD_START_CLEAR 8 /**< Offset to start clear */
#define XAXIDMA_BD_BYTES_TO_CLEAR 48 /**< BD specific bytes to be
* cleared */
#define XAXIDMA_BD_NUM_WORDS 16 /**< Total number of words for
* one BD*/
#define XAXIDMA_BD_HW_NUM_BYTES 52 /**< Number of bytes hw used */
/* The offset of the last app word.
*/
#define XAXIDMA_LAST_APPWORD 4
/*@}*/
/** @name Bitmasks of XAXIDMA_BD_CTRL_OFFSET register
* @{
*/
#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /**< First tx packet */
#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /**< Last tx packet */
#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /**< All control bits */
/*@}*/
/** @name Bitmasks of XAXIDMA_BD_STS_OFFSET register
* @{
*/
#define XAXIDMA_BD_STS_COMPLETE_MASK 0x80000000 /**< Completed */
#define XAXIDMA_BD_STS_DEC_ERR_MASK 0x40000000 /**< Decode error */
#define XAXIDMA_BD_STS_SLV_ERR_MASK 0x20000000 /**< Slave error */
#define XAXIDMA_BD_STS_INT_ERR_MASK 0x10000000 /**< Internal err */
#define XAXIDMA_BD_STS_ALL_ERR_MASK 0x70000000 /**< All errors */
#define XAXIDMA_BD_STS_RXSOF_MASK 0x08000000 /**< First rx pkt */
#define XAXIDMA_BD_STS_RXEOF_MASK 0x04000000 /**< Last rx pkt */
#define XAXIDMA_BD_STS_ALL_MASK 0xFC000000 /**< All status bits */
/*@}*/
/** @name Bitmasks and shift values for XAXIDMA_BD_MCCTL_OFFSET register
* @{
*/
#define XAXIDMA_BD_TDEST_FIELD_MASK 0x0000000F
#define XAXIDMA_BD_TID_FIELD_MASK 0x00000F00
#define XAXIDMA_BD_TUSER_FIELD_MASK 0x000F0000
#define XAXIDMA_BD_ARCACHE_FIELD_MASK 0x0F000000
#define XAXIDMA_BD_ARUSER_FIELD_MASK 0xF0000000
#define XAXIDMA_BD_TDEST_FIELD_SHIFT 0
#define XAXIDMA_BD_TID_FIELD_SHIFT 8
#define XAXIDMA_BD_TUSER_FIELD_SHIFT 16
#define XAXIDMA_BD_ARCACHE_FIELD_SHIFT 24
#define XAXIDMA_BD_ARUSER_FIELD_SHIFT 28
/** @name Bitmasks and shift values for XAXIDMA_BD_STRIDE_VSIZE_OFFSET register
* @{
*/
#define XAXIDMA_BD_STRIDE_FIELD_MASK 0x0000FFFF
#define XAXIDMA_BD_VSIZE_FIELD_MASK 0xFFF80000
#define XAXIDMA_BD_STRIDE_FIELD_SHIFT 0
#define XAXIDMA_BD_VSIZE_FIELD_SHIFT 19
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define XAxiDma_In32 Xil_In32
#define XAxiDma_Out32 Xil_Out32
/*****************************************************************************/
/**
*
* Read the given register.
*
* @param BaseAddress is the base address of the device
* @param RegOffset is the register offset to be read
*
* @return The 32-bit value of the register
*
* @note
* C-style signature:
* u32 XAxiDma_ReadReg(u32 BaseAddress, u32 RegOffset)
*
******************************************************************************/
#define XAxiDma_ReadReg(BaseAddress, RegOffset) \
XAxiDma_In32((BaseAddress) + (RegOffset))
/*****************************************************************************/
/**
*
* Write the given register.
*
* @param BaseAddress is the base address of the device
* @param RegOffset is the register offset to be written
* @param Data is the 32-bit value to write to the register
*
* @return None.
*
* @note
* C-style signature:
* void XAxiDma_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
******************************************************************************/
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data) \
XAxiDma_Out32((BaseAddress) + (RegOffset), (Data))
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,251 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_porting_guide.h
*
* This is a guide on how to move from using the xlldma driver to use xaxidma
* driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 05/18/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 4.00a rkv 02/22/11 Added support for simple DMA mode
* 6.00a srt 03/27/12 Added support for MCDMA mode
* 7.00a srt 06/18/12 API calls are reverted back for backward compatibility.
*
* </pre>
*
* <b>Overview</b>
*
* The API for xaxidma driver is similar to xlldma driver. The prefix for the
* API functions and structures is XAxiDma_ for the xaxidma driver.
*
* Due to hardware feature changes, signatures of some API functions are a
* little bit different from the xlldma API functions.
*
* We present API functions:
* - That only have prefix changes
* - That have different return type
* - That are new API functions
* - That have been removed
*
* Note that data structures have different prefix of XAxiDma_. Those API
* functions, that have data structures with prefix change, are considered as
* prefix change.
*
* <b>API Functions That Only Have Prefix Changes</b>
*
* <pre>
* xlldma driver | xaxidma driver (upto v5_00_a)
* -----------------------------------------------------------------------
* XLlDma_Reset(...) | XAxiDma_Reset(...)
* XLlDma_BdRingSnapShotCurrBd(...)| XAxiDma_BdRingSnapShotCurrBd(...)
* XLlDma_BdRingNext(...) | XAxiDma_BdRingNext(...)
* XLlDma_BdRingPrev(...) | XAxiDma_BdRingPrev(...)
* XLlDma_BdRingGetSr(...) | XAxiDma_BdRingGetSr(...)
* XLlDma_BdRingBusy(...) | XAxiDma_BdRingBusy(...)
* XLlDma_BdRingIntEnable(...) | XAxiDma_BdRingIntEnable(...)
* XLlDma_BdRingIntDisable(...) | XAxiDma_BdRingIntDisable(...)
* XLlDma_BdRingIntGetEnabled(...) | XAxiDma_BdRingIntGetEnabled(...)
* XLlDma_BdRingGetIrq(...) | XAxiDma_BdRingGetIrq(...)
* XLlDma_BdRingAckIrq(...) | XAxiDma_BdRingAckIrq(...)
* XLlDma_BdRingCreate(...) | XAxiDma_BdRingCreate(...)
* XLlDma_BdRingClone(...) | XAxiDma_BdRingClone(...)
* XLlDma_BdRingAlloc(...) | XAxiDma_BdRingAlloc(...)
* XLlDma_BdRingUnAlloc(...) | XAxiDma_BdRingUnAlloc(...)
* XLlDma_BdRingToHw(...) | XAxiDma_BdRingToHw(...)
* XLlDma_BdRingFromHw(...) | XAxiDma_BdRingFromHw(...)
* XLlDma_BdRingFree(...) | XAxiDma_BdRingFree(...)
* XLlDma_BdRingStart(...) | XAxiDma_BdRingStart(...)
* XLlDma_BdRingCheck(...) | XAxiDma_BdRingCheck(...)
* XLlDma_BdRingSetCoalesce(...) | XAxiDma_BdRingSetCoalesce(...)
* XLlDma_BdRingGetCoalesce(...) | XAxiDma_BdRingGetCoalesce(...)
* XLlDma_BdRead(...) | XAxiDma_BdRead(...)
* XLlDma_BdWrite(...) | XAxiDma_BdWrite(...)
* XLlDma_BdClear(...) | XAxiDma_BdClear(...)
* XLlDma_BdSetId(...) | XAxiDma_BdSetId(...)
* XLlDma_BdGetId(...) | XAxiDma_BdGetId(...)
* XLlDma_BdGetLength(...) | XAxiDma_BdGetLength(...)
* XLlDma_BdGetBufAddr(...) | XAxiDma_BdGetBufAddr(...)
*
*</pre>
*
* <b>API Functions That Have Different Return Type</b>
*
* Due to possible hardware failures, The caller should check the return value
* of the following functions.
*
* <pre>
* xlldma driver | xaxidma driver
* -----------------------------------------------------------------------
* void XLlDma_Pause(...) | int XAxiDma_Pause(...)
* void XLlDma_Resume(...) | int XAxiDma_Resume(...)
* </pre>
*
* The following functions have return type changed:
*
* <pre>
* xlldma driver | xaxidma driver
* -----------------------------------------------------------------------
* XLlDma_BdRing XLlDma_GetRxRing(...)| XAxiDma_BdRing * XAxiDma_GetRxRing(...)
* XLlDma_BdRing XLlDma_GetTxRing(...)| XAxiDma_BdRing * XAxiDma_GetTxRing(...)
* u32 XLlDma_BdRingMemCalc(...) | int XAxiDma_BdRingMemCalc(...)
* u32 XLlDma_BdRingCntCalc(...) | int XAxiDma_BdRingCntCalc(...)
* u32 XLlDma_BdRingGetCnt(...) | int XAxiDma_BdRingGetCnt(...)
* u32 XLlDma_BdRingGetFreeCnt(...) | int XAxiDma_BdRingGetFreeCnt(...)
* void XLlDma_BdSetLength(...) | int XAxiDma_BdSetLength(...)
* void XLlDma_BdSetBufAddr(...) | int XAxiDma_BdSetBufAddr(...)
*</pre>
*
* <b>API Functions That Are New API Functions</b>
*
* Now that the AXI DMA core is a standalone core, some new API are intrduced.
* Some other functions are added due to hardware interface change, so to
* replace old API functions.
*
* - XAxiDma_Config *XAxiDma_LookupConfig(u32 DeviceId);
* - int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config);
* - int XAxiDma_ResetIsDone(XAxiDma * InstancePtr);
* - XAxiDma_Bd * XAxiDma_BdRingGetCurrBd(XAxiDma_BdRing* RingPtr);
* - int XAxiDma_BdRingHwIsStarted(XAxiDma_BdRing* RingPtr);
* - void XAxiDma_BdRingDumpRegs(XAxiDma_BdRing *RingPtr);
* - int XAxiDma_StartBdRingHw(XAxiDma_BdRing* RingPtr);
* - void XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data);
* - u32 XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr);
* - u32 XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr);
* - int XAxiDma_BdHwCompleted(XAxiDma_Bd* BdPtr);
* - int XAxiDma_BdGetActualLength(XAxiDma_Bd* BdPtr);
* - int XAxiDma_BdSetAppWord(XAxiDma_Bd * BdPtr, int Offset, u32 Word);
* - u32 XAxiDma_BdGetAppWord(XAxiDma_Bd * BdPtr, int Offset, int *Valid);
*
* <b>API Functions That Have Been Removed</b>
*
* Please see individual function comments for how to replace the removed API
* function with new API functions.
*
* - void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress).
* This function is replaced by XAxiDma_LookupConfig()/XAxiDma_CfgInitialize()
*
* - u32 XLlDma_BdRingGetCr(XLlDma_BdRing* RingPtr).
* This is replaced by XAxiDma_BdRingGetError(XAxiDma_BdRing* RingPtr)
*
* - u32 XLlDma_BdRingSetCr(XLlDma_BdRing* RingPtr, u32 Data).
* This function is covered by other API functions:
* - void XAxiDma_BdRingIntEnable(XAxiDma_BdRing* RingPtr, u32 Mask)
* - void XAxiDma_BdRingIntDisable(XAxiDma_BdRing* RingPtr, u32 Mask)
* - int XAxiDma_BdRingSetCoalesce(XAxiDma_BdRing * RingPtr, u32 Counter,
* u32 Timer)
*
* - u32 XLlDma_BdSetStsCtrl(XLlDma_Bd* BdPtr, u32 Data).
* Replaced by XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data);
*
* - u32 XLlDma_BdGetStsCtrl(XLlDma_Bd* BdPtr).
* Replaced by XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr) and
* XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr).
*
* <b>API Functions That Have Been Added to support simple DMA mode</b>
*
* - u32 XAxiDma_Busy(XAxiDma *InstancePtr,int Direction);
* - int XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, u32 BuffAddr, int Length,
* int Direction);
* - XAxiDma_HasSg(InstancePtr);
* - XAxiDma_IntrEnable(InstancePtr,Mask,Direction);
* - XAxiDma_IntrGetEnabled(InstancePtr, Direction);
* - XAxiDma_IntrDisable(InstancePtr, Mask, Direction);
* - XAxiDma_IntrGetIrq(InstancePtr, Direction);
* - XAxiDma_IntrAckIrq(InstancePtr, Mask, Direction);
*
* <b> For xaxidma driver v6_00_a Multiple Channel Support
* ---------------------------------------------------
* This driver supports Multi-channel mode and accordingly some APIs are
* changed to index multiple channels. Few new APIs are added.
* - Changed APIs
* * XAxiDma_GetRxRing(InstancePtr, RingIndex)
* * XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex)
* * XAxiDma_SimpleTransfer(XAxiDma *InstancePtr,
* u32 BuffAddr, u32 Length,
* int Direction, int RingIndex)
* * XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
* int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
* * XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr,
* u32 LenBytes, u32 LengthMask)
* * XAxiDma_BdGetActualLength(BdPtr, LengthMask)
* * XAxiDma_BdGetLength(BdPtr, LengthMask)
*
* - New APIs
* * XAxiDma_SelectKeyHole(XAxiDma *InstancePtr,
* int Direction, int Select)
* * XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr,
* int RingIndex)
* * XAxiDma_BdSetTId()
* * XAxiDma_BdGetTId()
* * XAxiDma_BdSetTDest()
* * XAxiDma_BdGetTDest()
* * XAxiDma_BdSetTUser()
* * XAxiDma_BdGetTUser()
* * XAxiDma_BdSetARCache()
* * XAxiDma_BdGetARCache()
* * XAxiDma_BdSetARUser()
* * XAxiDma_BdGetARUser()
* * XAxiDma_BdSetStride()
* * XAxiDma_BdGetStride()
* * XAxiDma_BdSetVSize()
* * XAxiDma_BdGetVSize()
* <b> For xaxidma driver v7_00_a
* ---------------------------------------------------
* - New API
* * XAxiDma_GetRxIndexRing(InstancePtr, RingIndex)
*
* - Changed APIs
* All the APIs changed in v6_00_a are reverted back for backward
* compatibility.
*</pre>
*
******************************************************************************/

View file

@ -0,0 +1,92 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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 xaxidma_sinit.c
*
* Look up the hardware settings using device ID. The hardware setting is inside
* the configuration table in xaxidma_g.c, generated automatically by XPS or
* manually by the user.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 08/16/10 First release
* 2.00a jz 08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
* updated tcl file, added xaxidma_porting_guide.h
* 3.00a jz 11/22/10 Support IP core parameters change
* 5.00a srt 08/29/11 Removed a compiler warning
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xaxidma.h"
/*****************************************************************************/
/**
* Look up the hardware configuration for a device instance
*
* @param DeviceId is the unique device ID of the device to lookup for
*
* @return
* The configuration structure for the device. If the device ID is
* not found,a NULL pointer is returned.
*
* @note None
*
******************************************************************************/
XAxiDma_Config *XAxiDma_LookupConfig(u32 DeviceId)
{
extern XAxiDma_Config XAxiDma_ConfigTable[];
XAxiDma_Config *CfgPtr;
u32 Index;
CfgPtr = NULL;
for (Index = 0; Index < XPAR_XAXIDMA_NUM_INSTANCES; Index++) {
if (XAxiDma_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XAxiDma_ConfigTable[Index];
break;
}
}
return CfgPtr;
}

View file

@ -0,0 +1,93 @@
/******************************************************************************
*
* Copyright (C) 2010 - 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.
*
******************************************************************************/
#ifndef _XDEBUG_H
#define _XDEBUG_H
#if defined(DEBUG) && !defined(NDEBUG)
#include <stdio.h>
#ifndef XDEBUG_WARNING
#define XDEBUG_WARNING
#warning DEBUG is enabled
#endif
#define XDBG_DEBUG_ERROR 0x00000001 /* error condition messages */
#define XDBG_DEBUG_GENERAL 0x00000002 /* general debug messages */
#define XDBG_DEBUG_ALL 0xFFFFFFFF /* all debugging data */
#define XDBG_DEBUG_FIFO_REG 0x00000100 /* display register reads/writes */
#define XDBG_DEBUG_FIFO_RX 0x00000101 /* receive debug messages */
#define XDBG_DEBUG_FIFO_TX 0x00000102 /* transmit debug messages */
#define XDBG_DEBUG_FIFO_ALL 0x0000010F /* all fifo debug messages */
#define XDBG_DEBUG_TEMAC_REG 0x00000400 /* display register reads/writes */
#define XDBG_DEBUG_TEMAC_RX 0x00000401 /* receive debug messages */
#define XDBG_DEBUG_TEMAC_TX 0x00000402 /* transmit debug messages */
#define XDBG_DEBUG_TEMAC_ALL 0x0000040F /* all temac debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_RX 0x00000800 /* receive debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_TX 0x00000801 /* transmit debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_IOCTL 0x00000802 /* ioctl debug messages */
#define XDBG_DEBUG_TEMAC_ADPT_MISC 0x00000803 /* debug msg for other routines */
#define XDBG_DEBUG_TEMAC_ADPT_ALL 0x0000080F /* all temac adapter debug messages */
#define xdbg_current_types (XDBG_DEBUG_ERROR)
#define xdbg_stmnt(x) x
/* In VxWorks, if _WRS_GNU_VAR_MACROS is defined, special syntax is needed for
* macros that accept variable number of arguments
*/
#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS)
#define xdbg_printf(type, args...) (((type) & xdbg_current_types) ? printf (## args) : 0)
#else /* ANSI Syntax */
#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0)
#endif
#else /* defined(DEBUG) && !defined(NDEBUG) */
#define xdbg_stmnt(x)
/* See VxWorks comments above */
#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS)
#define xdbg_printf(type, args...)
#else /* ANSI Syntax */
#define xdbg_printf(...)
#endif
#endif /* defined(DEBUG) && !defined(NDEBUG) */
#endif /* _XDEBUG_H */