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:
parent
adbfea517d
commit
0f604c9902
21 changed files with 10904 additions and 0 deletions
43
XilinxProcessorIPLib/drivers/axidma/data/axidma.mdd
Executable file
43
XilinxProcessorIPLib/drivers/axidma/data/axidma.mdd
Executable 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
|
208
XilinxProcessorIPLib/drivers/axidma/data/axidma.tcl
Executable file
208
XilinxProcessorIPLib/drivers/axidma/data/axidma.tcl
Executable 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
|
||||
}
|
22
XilinxProcessorIPLib/drivers/axidma/examples/index.html
Executable file
22
XilinxProcessorIPLib/drivers/axidma/examples/index.html
Executable 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
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
27
XilinxProcessorIPLib/drivers/axidma/src/Makefile
Normal file
27
XilinxProcessorIPLib/drivers/axidma/src/Makefile
Normal 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)
|
953
XilinxProcessorIPLib/drivers/axidma/src/xaxidma.c
Normal file
953
XilinxProcessorIPLib/drivers/axidma/src/xaxidma.c
Normal 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;
|
||||
}
|
727
XilinxProcessorIPLib/drivers/axidma/src/xaxidma.h
Normal file
727
XilinxProcessorIPLib/drivers/axidma/src/xaxidma.h
Normal 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 */
|
339
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bd.c
Normal file
339
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bd.c
Normal 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");
|
||||
}
|
671
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bd.h
Normal file
671
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bd.h
Normal 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 */
|
1533
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.c
Normal file
1533
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.c
Normal file
File diff suppressed because it is too large
Load diff
522
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.h
Normal file
522
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_bdring.h
Normal 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 */
|
83
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_g.c
Normal file
83
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_g.c
Normal 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
|
||||
}
|
||||
};
|
331
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_hw.h
Normal file
331
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_hw.h
Normal 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
|
251
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_porting_guide.h
Normal file
251
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_porting_guide.h
Normal 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>
|
||||
*
|
||||
******************************************************************************/
|
92
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_sinit.c
Normal file
92
XilinxProcessorIPLib/drivers/axidma/src/xaxidma_sinit.c
Normal 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;
|
||||
}
|
93
XilinxProcessorIPLib/drivers/axidma/src/xdebug.h
Normal file
93
XilinxProcessorIPLib/drivers/axidma/src/xdebug.h
Normal 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 */
|
Loading…
Add table
Reference in a new issue