emaclite_v4_0: Deprecated older version and created new minor version.

This patch deprecates emaclite_v4_0 and creates new
minor version emaclite_v4_1.

Signed-off-by: Naga Sureshkumar Relli <nagasure@xilinx.com>
This commit is contained in:
Naga Sureshkumar Relli 2015-07-13 16:29:01 +05:30 committed by Nava kishore Manne
parent 206f4fe1d7
commit a548e9f27b
27 changed files with 8060 additions and 0 deletions

View file

@ -0,0 +1,7 @@
xemaclite_selftest_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_polled_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_intr_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_phy_loopback_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_ping_req_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_ping_reply_example.c=xemaclite_example.h,xemaclite_example_util.c
xemaclite_internal_loopback_example=xemaclite_example.h,xemaclite_example_util.c

View file

@ -0,0 +1,47 @@
###############################################################################
#
# Copyright (C) 2004 - 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
# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
# MODIFICATION HISTORY:
#
# Ver Who Date Changes
# -------- ------ -------- --------------------------------------------------
# 4.0 adk 10/12/13 Removed support for xps emaclite
##############################################################################
OPTION psf_version = 2.1;
BEGIN driver emaclite
OPTION supported_peripherals = (axi_ethernetlite);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 4.1;
OPTION NAME = emaclite;
END driver

View file

@ -0,0 +1,57 @@
###############################################################################
#
# Copyright (C) 2004 - 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
# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
# Modification History
#
# Ver Who Date Changes
# ----- ---- -------- -----------------------------------------------
# 4.0 adk 10/12/13 Updated as per the New Tcl API's
#####################################################################
## @BEGIN_CHANGELOG EDK_M
## Removed the local ::hsi::utils::define_canonical_xpars API as there is
## a common API in the tcl of the tools
##
## @END_CHANGELOG
## @BEGIN_CHANGELOG EDK_LS3
## Updated to handle the corner cases described in CR #518193 while
## generating canonical definitions
##
## @END_CHANGELOG
#uses "xillib.tcl"
proc generate {drv_handle} {
::hsi::utils::define_include_file $drv_handle "xparameters.h" "XEmacLite" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK"
::hsi::utils::define_config_file $drv_handle "xemaclite_g.c" "XEmacLite" "DEVICE_ID" "C_BASEADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK"
::hsi::utils::define_canonical_xpars $drv_handle "xparameters.h" "EmacLite" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_TX_PING_PONG" "C_RX_PING_PONG" "C_INCLUDE_MDIO" "C_INCLUDE_INTERNAL_LOOPBACK"
}

View file

@ -0,0 +1,42 @@
/******************************************************************************
*
* Copyright (C) 2003 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef EMACLITE_HEADER_H /* prevent circular inclusions */
#define EMACLITE_HEADER_H /* by using protection macros */
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
int EmacLitePolledExample(u16 DeviceId);
#endif

View file

@ -0,0 +1,52 @@
/******************************************************************************
*
* Copyright (C) 2003 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef EMACLITE_INTR_HEADER_H /* prevent circular inclusions */
#define EMACLITE_INTR_HEADER_H /* by using protection macros */
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#ifdef XPAR_INTC_0_DEVICE_ID
int EmacLiteIntrExample(XIntc* IntcInstancePtr,
XEmacLite* EmacLiteInstPtr,
u16 EmacLiteDeviceId,
u16 EmacLiteIntrId);
#else
int EmacLiteIntrExample(XScuGic* IntcInstancePtr,
XEmacLite* EmacLiteInstPtr,
u16 EmacLiteDeviceId,
u16 EmacLiteIntrId);
#endif
#endif

View file

@ -0,0 +1,227 @@
###############################################################################
#
# Copyright (C) 2005 - 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
# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
#
# Ver Who Date Changes
# ----- ---- -------- -----------------------------------------------
# 4.0 adk 10/12/13 Updated as per the New Tcl API's
##############################################################################
## @BEGIN_CHANGELOG EDK_I
##
## - include header files
##
## @END_CHANGELOG
## @BEGIN_CHANGELOG EDK_H
##
## - Initial Revision
##
## @END_CHANGELOG
## @BEGIN_CHANGELOG EDK_LS2
##
## - Updated the tcl to use additional files provided with the examples
##
## @END_CHANGELOG
# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl
# -----------------------------------------------------------------
# Software Project Types (swproj):
# 0 : MemoryTest - Calls basic memorytest routines from common driver dir
# 1 : PeripheralTest - Calls any existing polled_example and/or selftest
# -----------------------------------------------------------------
# -----------------------------------------------------------------
# TCL Procedures:
# -----------------------------------------------------------------
proc gen_include_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
if {$ifemacliteintr == 1} {
set inc_file_lines {xemaclite.h xemaclite_example.h emaclite_header.h emaclite_intr_header.h}
} else {
set inc_file_lines {xemaclite.h xemaclite_example.h emaclite_header.h}
}
return $inc_file_lines
}
}
proc gen_src_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
if {$ifemacliteintr == 1} {
set inc_file_lines {examples/xemaclite_example.h examples/xemaclite_polled_example.c examples/xemaclite_intr_example.c examples/xemaclite_example_util.c data/emaclite_header.h data/emaclite_intr_header.h}
} else {
set inc_file_lines {examples/xemaclite_example.h examples/xemaclite_polled_example.c examples/xemaclite_example_util.c data/emaclite_header.h}
}
return $inc_file_lines
}
}
proc gen_testfunc_def {swproj mhsinst} {
return ""
}
proc gen_init_code {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set ipname [common::get_property NAME $mhsinst]
set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
if {$ifemacliteintr == 1} {
set decl " static XEmacLite ${ipname}_EmacLite;"
set inc_file_lines $decl
return $inc_file_lines
} else {
return ""
}
}
}
proc gen_testfunc_call {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
set ifemacliteintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
set ipname [common::get_property NAME $mhsinst]
set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"]
set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]]
if { $stdout == "" || $stdout == "none" } {
set hasStdout 0
} else {
set hasStdout 1
}
if {$ifemacliteintr == 1} {
set intr_pin_name [hsi::get_pins -of_objects [hsi::get_cells $ipname] -filter "TYPE==INTERRUPT"]
set intcname [::hsi::utils::get_connected_intr_cntrl $ipname $intr_pin_name]
set intcvar intc
set proc [common::get_property IP_NAME [hsi::get_cells [hsi::get_sw_processor]]]
}
set testfunc_call ""
if {${hasStdout} == 0} {
append testfunc_call "
{
int status;
status = EmacLitePolledExample(${deviceid});
}"
if {$ifemacliteintr == 1} {
if {
$proc == "microblaze"
} then {
set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR"
} else {
set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR"
}
set intr_id [string toupper $intr_id]
append testfunc_call "
{
int Status;
Status = EmacLiteIntrExample(&${intcvar}, &${ipname}_EmacLite, \\
${deviceid}, \\
${intr_id});
}"
}
} else {
append testfunc_call "
{
int status;
print(\"\\r\\nRunning EmacLitePolledExample() for ${ipname}...\\r\\n\");
status = EmacLitePolledExample(${deviceid});
if (status == 0) {
print(\"EmacLite Polled Example PASSED\\r\\n\");
}
else {
print(\"EmacLite Polled Example FAILED\\r\\n\");
}
}"
if {$ifemacliteintr == 1} {
if {
$proc == "microblaze"
} then {
set intr_id "XPAR_${intcname}_${ipname}_${intr_pin_name}_INTR"
} else {
set intr_id "XPAR_FABRIC_${ipname}_${intr_pin_name}_INTR"
}
set intr_id [string toupper $intr_id]
append testfunc_call "
{
int Status;
print(\"\\r\\n Running Interrupt Test for ${ipname}...\\r\\n\");
Status = EmacLiteIntrExample(&${intcvar}, &${ipname}_EmacLite, \\
${deviceid}, \\
${intr_id});
if (Status == 0) {
print(\"EmacLite Interrupt Test PASSED\\r\\n\");
}
else {
print(\"EmacLite Interrupt Test FAILED\\r\\n\");
}
}"
}
}
return $testfunc_call
}

View file

@ -0,0 +1,24 @@
<!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 emaclite_v4_0 </h1>
<HR>
<ul>
<li>xemaclite_ping_reply_example.c <a href="xemaclite_ping_reply_example.c">(source)</a> </li>
<li>xemaclite_ping_req_example.c <a href="xemaclite_ping_req_example.c">(source)</a> </li>
<li>xemaclite_phy_loopback_example.c <a href="xemaclite_phy_loopback_example.c">(source)</a> </li>
<li>xemaclite_example_util.c <a href="xemaclite_example_util.c">(source)</a> </li>
<li>xemaclite_intr_example.c <a href="xemaclite_intr_example.c">(source)</a> </li>
<li>xemaclite_internal_loopback_example.c <a href="xemaclite_internal_loopback_example.c">(source)</a> </li>
<li>xemaclite_polled_example.c <a href="xemaclite_polled_example.c">(source)</a> </li>
<li>xemaclite_selftest_example.c <a href="xemaclite_selftest_example.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>

View file

@ -0,0 +1,134 @@
/******************************************************************************
*
* Copyright (C) 2009 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_example.h
*
* Defines common data types, prototypes, and includes the proper headers
* for use with the EmacLite example code residing in this directory.
*
* This file along with xemaclite_example_util.c are utilized with the specific
* example code in the other source code files provided.
*
* These examples are designed to be compiled and utilized within the EDK
* standalone BSP development environment. The readme file contains more
* information on build requirements needed by these examples.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 2.00a ktn 04/13/09 First release
* 3.03a bss 09/01/12 Moved the declarations of RecvFrameLength
* TransmitComplete, EmacLiteInstance,
* TxFrame[XEL_MAX_FRAME_SIZE], RxFrame[XEL_MAX_FRAME_SIZE];
* to xemaclite_example_util.c for fixing C++ compilation
* errors
* </pre>
*
******************************************************************************/
#ifndef XEMACLITE_EXAMPLE_H
#define XEMACLITE_EXAMPLE_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xemaclite.h"
/************************** Constant Definitions ****************************/
#define PHY_REG0_OFFSET 0 /* Register 0 of PHY device */
#define PHY_REG1_OFFSET 1 /* Register 1 of PHY device */
#define PHY_REG0_RESET_MASK 0x8000 /* Reset Phy device */
#define PHY_REG0_LOOPBACK_MASK 0x4000 /* Loopback Enable in Phy */
#define PHY_REG0_SPD_100_MASK 0x2000 /* Speed of 100Mbps for Phy */
#define PHY_REG1_DETECT_MASK 0x1808 /* Mask to detect PHY device */
#define EMACLITE_PHY_DELAY_SEC 4 /* Amount of time to delay waiting on
* PHY to reset.
*/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions ******************************/
/************************** Function Prototypes *****************************/
/*
* Utility functions implemented in xemaclite_example_util.c
*/
void EmacLitePhyDelay(unsigned int Seconds);
u32 EmacLitePhyDetect(XEmacLite *InstancePtr);
int EmacLiteEnablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress);
int EmacLiteDisablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress);
/************************** Variable Definitions ****************************/
/*
* Set up valid local MAC addresses. This loop back test uses the LocalAddress
* both as a source and destination MAC address.
*/
extern XEmacLite EmacLiteInstance; /* Instance of the EmacLite */
/*
* Buffers used for Transmission and Reception of Packets. These are declared
* as global so that they are not a part of the stack.
*/
extern u8 TxFrame[XEL_MAX_FRAME_SIZE];
extern u8 RxFrame[XEL_MAX_FRAME_SIZE];
extern volatile u32 RecvFrameLength; /* Indicates the length of the
* Received packet
*/
extern volatile int TransmitComplete; /* Flag to indicate that the
* Transmission is complete
*/
#ifdef __cplusplus
}
#endif
#endif /* XEMACLITE_EXAMPLE_H */

View file

@ -0,0 +1,60 @@
xemaclite_example_readme.txt
-------------------------
The examples in this directory are provided to give the user some idea of
how the EmacLite and its driver/examples are intended to be used.
SYSTEM REQUIREMENTS
The system containing the EmacLite should have the following capabilities:
- Processor based system
- At least one EmacLite core
- An interrupt controller
- An external memory controller with at least 200KB of RAM available
- A UART to display messages
FILES
1. xemaclite_example.h - Top level include for all examples.
This file needs to be included in xemaclite_phy_loopback_example,
xemaclite_polled_example, xemaclite_intr_example and
xemaclite_internal_loopback_example.c
2. xemaclite_example_util.c - Provide various functions for Phy setup.
This file needs to be used with xemaclite_phy_loopback_example,
xemaclite_polled_example, xemaclite_intr_example and
xemaclite_internal_loopback_example.c
3. xemaclite_polled_example.c - Example using the emaclite driver
in polled mode.
4. xemaclite_intr_example.c - Example using the emaclite driver
in interrupt mode.
5. xemaclite_phy_loopback_example.c - Example using the emaclite driver
in interrupt mode using the MAC loop back in the PHY. This example can
be run only when the MDIO interface is configured in the EmacLite core.
6. xemaclite_ping_rq_example.c - This is a polled mode example generating a
ping request for a specified IP address.
7. xemaclite_ping_reply_example.c - This is a polled mode example generating a
ping reply when it receives a ping packet from the external world.
8. xemaclite_selftest_example.c - This is a example based on the self test.
9.xemaclite_internal_loopback_example.c -
This file contains an interrupt example outlining the use of interrupts and
callbacks in the transmission/reception of Ethernet frames using internal
loop back with an incrementing payload from 1 byte to 1500 bytes (excluding
Ethernet Header and FCS).
INCLUDING EXAMPLES IN EDK/SDK
Each example is independent from the others except for common code found in
xemaclite_example_util.c. When including source code files in an EDK/SDK SW
application, select xemaclite_example_util.c along with one other example
source code file.

View file

@ -0,0 +1,272 @@
/******************************************************************************
*
* Copyright (C) 2009 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_example_util.c
*
* This file implements the utility functions for the EmacLite example code.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 2.00a ktn 04/13/09 First release
* 2.00a ktn 06/13/09 Changed the EmacLitePhyDetect function so that
* the function is not in an infinite loop in case of a
* faulty Phy device.
* 3.03a bss 09/01/12 Moved the declarations of RecvFrameLength,
* TransmitComplete, EmacLiteInstance
* TxFrame[XEL_MAX_FRAME_SIZE], RxFrame[XEL_MAX_FRAME_SIZE]
* from the xemaclite_example.h
* to this file for fixing C++ compilation errors
*</pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_example.h"
#include "stdio.h"
/************************** Variable Definitions ****************************/
/*
* Set up valid local MAC addresses. This loop back test uses the LocalAddress
* both as a source and destination MAC address.
*/
XEmacLite EmacLiteInstance; /* Instance of the EmacLite */
/*
* Buffers used for Transmission and Reception of Packets. These are declared
* as global so that they are not a part of the stack.
*/
u8 TxFrame[XEL_MAX_FRAME_SIZE];
u8 RxFrame[XEL_MAX_FRAME_SIZE];
volatile u32 RecvFrameLength; /* Indicates the length of the Received packet
*/
volatile int TransmitComplete; /* Flag to indicate that the Transmission
* is complete
*/
/******************************************************************************/
/**
*
* This function detects the PHY address by looking for successful MII status
* register contents (PHY register 1). It looks for a PHY that supports
* auto-negotiation and 10Mbps full-duplex and half-duplex. So, this code
* won't work for PHYs that don't support those features, but it's a bit more
* general purpose than matching a specific PHY manufacturer ID.
*
* Note also that on some (older) Xilinx ML4xx boards, PHY address 0 does not
* properly respond to this query. But, since the default is 0 and assuming
* no other address responds, then it seems to work OK.
*
* @param InstancePtr is the pointer to the instance of EmacLite driver.
*
* @return The address of the PHY device detected (returns 0 if not
* detected).
*
* @note
* The bit mask (0x1808) of the MII status register
* (PHY Register 1) used in this function are:
* 0x1000: 10Mbps full duplex support.
* 0x0800: 10Mbps half duplex support.
* 0x0008: Auto-negotiation support.
*
******************************************************************************/
u32 EmacLitePhyDetect(XEmacLite *InstancePtr)
{
u16 PhyData;
int PhyAddr;
/*
* Verify all 32 MDIO ports.
*/
for (PhyAddr = 31; PhyAddr >= 0; PhyAddr--) {
XEmacLite_PhyRead(InstancePtr, PhyAddr, PHY_REG1_OFFSET,
&PhyData);
if (PhyData != 0xFFFF) {
if ((PhyData & PHY_REG1_DETECT_MASK) ==
PHY_REG1_DETECT_MASK) {
return PhyAddr; /* Found a valid PHY device */
}
}
}
/*
* Unable to detect PHY device returning the default address of 0.
*/
return 0;
}
/******************************************************************************/
/**
*
* This function enables the MAC loopback on the PHY.
*
* @param InstancePtr is the pointer to the instance of EmacLite driver.
* @param PhyAddress is the address of the Phy device.
*
* @return
* - XST_SUCCESS if the loop back is enabled.
* - XST_FAILURE if the loop back was not enabled.
*
* @note None.
*
******************************************************************************/
int EmacLiteEnablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress)
{
int Status;
u16 PhyData = 0;
/*
* Set the speed and put the PHY in reset.
*/
PhyData |= PHY_REG0_SPD_100_MASK;
Status = XEmacLite_PhyWrite(InstancePtr, PhyAddress, PHY_REG0_OFFSET,
PhyData | PHY_REG0_RESET_MASK);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Give sufficient delay for Phy Reset.
*/
EmacLitePhyDelay(EMACLITE_PHY_DELAY_SEC);
/*
* Set the PHY in loop back.
*/
XEmacLite_PhyWrite(InstancePtr, PhyAddress, PHY_REG0_OFFSET,
PhyData | PHY_REG0_LOOPBACK_MASK);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Give sufficient delay for Phy Loopback Enable.
*/
EmacLitePhyDelay(1);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function disables the MAC loopback on the PHY.
*
* @param InstancePtr is the pointer to the instance of EmacLite driver.
* @param PhyAddress is the address of the Phy device.
*
* @return
* - XST_SUCCESS if the loop back was disabled.
* - XST_FAILURE if the loop back was not disabled.
*
* @note None.
*
******************************************************************************/
int EmacLiteDisablePhyLoopBack(XEmacLite *InstancePtr, u32 PhyAddress)
{
int Status;
u16 PhyData;
/*
* Disable loop back through PHY register using MDIO support.
*/
Status = XEmacLite_PhyRead(InstancePtr, PhyAddress, PHY_REG0_OFFSET,
&PhyData);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XEmacLite_PhyWrite(InstancePtr,PhyAddress, PHY_REG0_OFFSET,
PhyData & ~(PHY_REG0_LOOPBACK_MASK));
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* For PPC we use a usleep call, for Microblaze we use an assembly loop that
* is roughly the same regardless of optimization level, although caches and
* memory access time can make the delay vary. Just keep in mind that after
* resetting or updating the PHY modes, the PHY typically needs time to recover.
*
* @return None
*
* @note None
*
******************************************************************************/
void EmacLitePhyDelay(unsigned int Seconds)
{
#ifdef __MICROBLAZE__
static int WarningFlag = 0;
/* If MB caches are disabled or do not exist, this delay loop could
* take minutes instead of seconds (e.g., 30x longer). Print a warning
* message for the user (once). If only MB had a built-in timer!
*/
if (((mfmsr() & 0x20) == 0) && (!WarningFlag)) {
#ifdef STDOUT_BASEADDRESS
xil_printf("Warning: This example will take ");
xil_printf("minutes to complete without I-cache enabled \r\n");
#endif
WarningFlag = 1;
}
#define ITERS_PER_SEC (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 6)
asm volatile ("\n"
"1: \n\t"
"addik r7, r0, %0 \n\t"
"2: \n\t"
"addik r7, r7, -1 \n\t"
"bneid r7, 2b \n\t"
"or r0, r0, r0 \n\t"
"bneid %1, 1b \n\t"
"addik %1, %1, -1 \n\t"
:: "i"(ITERS_PER_SEC), "d" (Seconds));
#else
usleep(Seconds * 1000000);
#endif
}

View file

@ -0,0 +1,580 @@
/******************************************************************************
*
* Copyright (C) 2003 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_internal_loopback_example.c
*
* This file contains a example for using EmacLite hardware and driver.
* This file contains an interrupt example outlining the use of interrupts and
* callbacks in the transmission/reception of Ethernet frames using internal
* loop back with an incrementing payload from 1 byte to 1500 bytes (excluding
* Ethernet Header and FCS).
*
* This example assumes that there is an interrupt controller in the hardware
* system and the EmacLite device is connected to the interrupt controller.
*
* @note
*
* None
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 05/21/04 First release
* 1.01a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines
* 2.00a ktn 02/25/09 Updated to use internal loop back feature
* 2.01a ktn 07/20/09 Updated the example to wait for either Transmit complete
* or Rx packet reception.
* 3.00a ktn 10/22/09 Updated the example to use the HAL APIs/macros.
* Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 07/08/10 Updated example to support Little Endian MicroBlaze.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_example.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int EmacLiteIntrLoopbackExample(u16 DeviceId);
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize);
static int EmacLiteRecvFrame(u32 PayloadSize);
static void EmacLiteRecvHandler(void *CallBackRef);
static void EmacLiteSendHandler(void *CallBackRef);
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId);
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId);
/************************** Variable Definitions ****************************/
XIntc IntcInstance; /* Instance of the Interrupt Controller */
/*
* Set up valid local MAC addresses. This loop back test uses the LocalAddress
* both as a source and destination MAC address.
*/
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03
};
/******************************************************************************/
/**
*
* This function is the main function of the EmacLite example in interrupt mode.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int main()
{
int Status;
/*
* Run the EmacLite example , specify the Device ID that is
* generated in xparameters.h.
*/
Status = EmacLiteIntrLoopbackExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The main entry point for the EmacLite driver in interrupt mode example.
* This function will transmit/receive the frame using internal loop back and
* verify the data in the received frame.
*
* @param DeviceId is device ID of the XEmacLite Device , typically
* XPAR_<EMAC_instance>_DEVICE_ID value from xparameters.h.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int EmacLiteIntrLoopbackExample(u16 DeviceId)
{
int Status;
XIntc *IntcInstancePtr;
XEmacLite *EmacLiteInstPtr;
u32 TxLength;
XEmacLite_Config *ConfigPtr;
RecvFrameLength = 0;
IntcInstancePtr = &IntcInstance;
EmacLiteInstPtr =&EmacLiteInstance;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr, ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress);
/*
* Set up the interrupt infrastructure.
*/
Status = EmacLiteSetupIntrSystem(IntcInstancePtr, EmacLiteInstPtr,
INTC_EMACLITE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the EmacLite handlers.
*/
XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteRecvHandler);
XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteSendHandler);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
/*
* Enable the EmacLite interrupts.
*/
XEmacLite_EnableInterrupts(EmacLiteInstPtr);
/*
* Check if there is a Tx buffer available.
*/
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) {
return XST_FAILURE;
}
/*
* Enable internal loop back.
*/
XEmacLite_EnableLoopBack(EmacLiteInstPtr);
/*
* Send/Receive frames of varying sizes and verify the data in the
* received frames.
*/
for (TxLength = 1; TxLength <= XEL_MTU_SIZE; ) {
RecvFrameLength = 0;
/*
* Send a frame.
*/
Status = EmacLiteSendFrame(EmacLiteInstPtr, TxLength);
if (Status != XST_SUCCESS) {
/*
* Disable internal loop back.
*/
XEmacLite_DisableLoopBack(EmacLiteInstPtr);
return XST_FAILURE;
}
/*
* Wait for the frame to be transmitted and received back.
* As the core is in loopback the transmit interrupt and the
* receive interrupt occur simulataneously.
*/
while ((RecvFrameLength == 0) && (TransmitComplete == FALSE));
/*
* Check the receive frame.
*/
Status = EmacLiteRecvFrame(TxLength++);
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) {
/*
* Disable internal loop back.
*/
XEmacLite_DisableLoopBack(EmacLiteInstPtr);
/*
* Disable and disconnect the EmacLite Interrupts.
*/
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr,
INTC_EMACLITE_ID);
return XST_FAILURE;
}
}
/*
* Disable internal loop back.
*/
XEmacLite_DisableLoopBack(EmacLiteInstPtr);
/*
* Disable and disconnect the EmacLite Interrupts.
*/
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function sends a frame of given size. This function assumes interrupt
* mode and sends the frame.
*
* @param XEmacInstancePtr is a pointer to the XEmacLite instance to be
* worked on.
* @param PayloadSize is the size of the frame to create. The size only
* reflects the payload size, it does not include the Ethernet
* header size (14 bytes) nor the Ethernet CRC size (4 bytes).
* @param DestAddress if the address of the remote hardware the frame is
* to be sent to.
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSendFrame(XEmacLite *XEmacInstancePtr, u32 PayloadSize)
{
u8 *FramePtr;
int Index;
int Status;
/*
* Set the Complete flag to false.
*/
TransmitComplete = FALSE;
/*
* Assemble the frame with a destination address and the source address.
*/
FramePtr = (u8 *)TxFrame;
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Fill in the source MAC address.
*/
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Set up the type/length field - be sure its in network order.
*/
*((u16 *)FramePtr) = Xil_Htons(PayloadSize);
FramePtr++;
FramePtr++;
/*
* Now fill in the data field with known values so we can verify them
* on receive.
*/
for (Index = 0; Index < PayloadSize; Index++) {
*FramePtr++ = (u8)Index;
}
/*
* Now send the frame.
*/
Status = XEmacLite_Send(XEmacInstancePtr, (u8 *)TxFrame,
PayloadSize + XEL_HEADER_SIZE);
return Status;
}
/******************************************************************************/
/**
*
* This function receives a frame of given size. This function assumes interrupt
* mode, receives the frame and verifies its contents.
*
* @param PayloadSize is the size of the frame to receive.
* The size only reflects the payload size, it does not include the
* Ethernet header size (14 bytes) nor the Ethernet CRC size (4
* bytes).
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int EmacLiteRecvFrame(u32 PayloadSize)
{
u8 *FramePtr;
/*
* This assumes MAC does not strip padding or CRC.
*/
if (RecvFrameLength != 0) {
int Index;
/*
* Verify length, which should be the payload size.
*/
if ((RecvFrameLength- (XEL_HEADER_SIZE + XEL_FCS_SIZE)) !=
PayloadSize) {
return XST_LOOPBACK_ERROR;
}
/*
* Verify the contents of the Received Frame.
*/
FramePtr = (u8 *)RxFrame;
FramePtr += XEL_HEADER_SIZE; /* Get past the header */
for (Index = 0; Index < PayloadSize; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_LOOPBACK_ERROR;
}
}
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function handles the receive callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteRecvHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Receive callback.
*/
RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame);
}
/******************************************************************************/
/**
*
* This function handles the transmit callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteSendHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Transmit callback.
*/
TransmitComplete = TRUE;
}
/*****************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the EmacLite device. This function is application specific since the
* actual system may or may not have an interrupt controller. The EmacLite
* could be directly connected to a processor without an interrupt controller.
* The user should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc.
* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId)
{
int Status;
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(IntcInstancePtr,
EmacLiteIntrId,
XEmacLite_InterruptHandler,
(void *)(EmacLiteInstPtr));
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#ifndef TESTAPP_GEN
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specific real mode so that
* the EmacLite can cause interrupts thru the interrupt controller.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Enable the interrupt for the EmacLite in the Interrupt controller.
*/
XIntc_Enable(IntcInstancePtr, EmacLiteIntrId);
#ifndef TESTAPP_GEN
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XIntc_InterruptHandler,
IntcInstancePtr);
/*
* Enable non-critical exceptions.
*/
Xil_ExceptionEnable();
#endif /* TESTAPP_GEN */
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the EmacLite device.
*
* @param IntcInstancePtr is the pointer to the instance of the INTC
* component.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId)
{
/*
* Disconnect and disable the interrupts for the EmacLite device.
*/
XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId);
}

View file

@ -0,0 +1,665 @@
/******************************************************************************
*
* Copyright (C) 2003 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_intr_example.c
*
* This file contains an example for using the EmacLite hardware and driver.
* This file contains an interrupt example outlining the use of interrupts and
* callbacks in the transmission/reception of an Ethernet frame of 1000 bytes of
* payload.
*
* If the MDIO interface is NOT configured in the EmacLite core then this example
* will transmit a frame.
* If the MDIO interface is configured in the EmacLite core then this example
* will enable the MAC loopback in the PHY device, then transmit the frame and
* compare the received frame.
*
* @note
*
* None
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 05/21/04 First release
* 1.01a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines
* 1.01a sv 06/06/06 Minor changes for supporting Test App Interrupt examples
* 2.00a ktn 02/25/09 Updated to use PHY loop back if MDIO is configured in
* core
* 3.00a ktn 10/22/09 Updated the example to use the HAL APIs/macros.
* Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 07/08/10 Updated example to support Little Endian MicroBlaze.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_example.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
#ifndef TESTAPP_GEN
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID
#endif
/*
* The Size of the Test Frame.
*/
#define EMACLITE_TEST_FRAME_SIZE 1000
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int EmacLiteIntrExample(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr,
u16 EmacLiteDeviceId,
u16 EmacLiteIntrId);
static int EmacLiteSendFrame(XEmacLite *EmacLiteInstPtr,
u32 PayloadSize);
static int EmacLiteRecvFrame(u32 PayloadSize);
static void EmacLiteRecvHandler(void *CallBackRef);
static void EmacLiteSendHandler(void *CallBackRef);
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId);
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId);
/************************** Variable Definitions *****************************/
XIntc IntcInstance; /* Instance of the Interrupt Controller */
/*
* Set up valid local and remote MAC addresses. This loop back test uses the
* LocalAddress both as a source and destination MAC address.
*/
static u8 RemoteAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x10, 0xa4, 0xb6, 0xfd, 0x09
};
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03
};
/****************************************************************************/
/**
*
* This function is the main function of the EmacLite interrupt example.
*
* @param None.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
*****************************************************************************/
#ifndef TESTAPP_GEN
int main()
{
int Status;
/*
* Run the EmacLite interrupt example , specify the parameters
* generated in xparameters.h.
*/
Status = EmacLiteIntrExample(&IntcInstance,
&EmacLiteInstance,
EMAC_DEVICE_ID,
INTC_EMACLITE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* The main entry point for the EmacLite driver example in interrupt mode.
* This function will transmit/receive the Ethernet frames and verify the
* data in the received frame (if the MDIO interface is configured in the
* EmacLite core).
* This function simply transmits a frame if the MDIO interface is not
* configured in the EmacLite core.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc.
* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite.
* @param EmacLiteDeviceId is device ID of the XEmacLite Device ,
* typically XPAR_<EMACLITE_instance>_DEVICE_ID value from
* xparameters.h.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID value from
* xparameters.h.
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int EmacLiteIntrExample(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr,
u16 EmacLiteDeviceId,
u16 EmacLiteIntrId)
{
int Status;
u32 PhyAddress = 0;
XEmacLite_Config *ConfigPtr;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(EmacLiteDeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
/*
* Check if there is a Tx buffer available, if there isn't it is an
* error.
*/
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) {
return XST_FAILURE;
}
/*
* Set up the interrupt infrastructure.
*/
Status = EmacLiteSetupIntrSystem(IntcInstancePtr,
EmacLiteInstPtr,
EmacLiteIntrId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the EmacLite handlers.
*/
XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteRecvHandler);
XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteSendHandler);
/*
* Enable the interrupts in the EmacLite controller.
*/
XEmacLite_EnableInterrupts(EmacLiteInstPtr);
RecvFrameLength = 0;
/*
* If the MDIO is configured in the device.
*/
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Detect the PHY device and enable the MAC Loop back
* in the PHY.
*/
PhyAddress = EmacLitePhyDetect(EmacLiteInstPtr);
Status = EmacLiteEnablePhyLoopBack(EmacLiteInstPtr,
PhyAddress);
if (Status != XST_SUCCESS) {
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr,
EmacLiteIntrId);
return XST_FAILURE;
}
}
/*
* Transmit an Ethernet frame.
*/
Status = EmacLiteSendFrame(EmacLiteInstPtr,
EMACLITE_TEST_FRAME_SIZE);
if (Status != XST_SUCCESS) {
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Disable the MAC Loop back in the PHY and
* disable/disconnect the EmacLite Interrupts.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr,
PhyAddress);
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr,
EmacLiteIntrId);
return XST_FAILURE;
}
}
/*
* Wait for the frame to be transmitted.
*/
while (TransmitComplete == FALSE);
/*
* If the MDIO is not configured in the core then return XST_SUCCESS
* as the frame has been transmitted.
*/
if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Disable and disconnect the EmacLite Interrupts.
*/
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr, EmacLiteIntrId);
return XST_SUCCESS;
}
/*
* Wait for the frame to be received.
*/
while (RecvFrameLength == 0);
/*
* Check the received frame.
*/
Status = EmacLiteRecvFrame(EMACLITE_TEST_FRAME_SIZE);
/*
* Diasble the Loop Back.
*/
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Disable the MAC Loop back in the PHY.
*/
Status |= EmacLiteDisablePhyLoopBack(EmacLiteInstPtr,
PhyAddress);
}
/*
* Disable and disconnect the EmacLite Interrupts.
*/
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr, EmacLiteIntrId);
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function sends a frame of given size. This function assumes interrupt
* mode and sends the frame.
*
* @param EmacLiteInstPtr is a pointer to the EmacLite instance.
* @param PayloadSize is the size of the frame to create. The size only
* reflects the payload size, it does not include the Ethernet
* header size (14 bytes) nor the Ethernet CRC size (4 bytes).
*
* @return XST_SUCCESS if successful, else XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSendFrame(XEmacLite *EmacLiteInstPtr, u32 PayloadSize)
{
int Status;
u8 *FramePtr;
u32 Index;
/*
* Set the Complete flag to false.
*/
TransmitComplete = FALSE;
/*
* Assemble the frame with a destination address and the source address.
*/
FramePtr = (u8 *)TxFrame;
/*
* Set up the destination address as the local address for
* Phy Loopback and Internal loopback.
*/
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr) ||
XEmacLite_IsLoopbackConfigured(EmacLiteInstPtr)) {
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
} else {
/*
* Fill in the valid Destination MAC address if
* the Loopback is not enabled.
*/
*FramePtr++ = RemoteAddress[0];
*FramePtr++ = RemoteAddress[1];
*FramePtr++ = RemoteAddress[2];
*FramePtr++ = RemoteAddress[3];
*FramePtr++ = RemoteAddress[4];
*FramePtr++ = RemoteAddress[5];
}
/*
* Fill in the source MAC address.
*/
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Set up the type/length field - be sure its in network order.
*/
*((u16 *)FramePtr) = Xil_Htons(PayloadSize);
FramePtr++;
FramePtr++;
/*
* Now fill in the data field with known values so we can verify them.
*/
for (Index = 0; Index < PayloadSize; Index++) {
*FramePtr++ = (u8)Index;
}
/*
* Now send the frame.
*/
Status = XEmacLite_Send(EmacLiteInstPtr, (u8 *)TxFrame,
PayloadSize + XEL_HEADER_SIZE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function receives a frame of given size. This function assumes interrupt
* mode, receives the frame and verifies its contents.
*
* @param PayloadSize is the size of the frame to receive.
* The size only reflects the payload size, it does not include the
* Ethernet header size (14 bytes) nor the Ethernet CRC size (4
* bytes).
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int EmacLiteRecvFrame(u32 PayloadSize)
{
u8 *FramePtr;
/*
* This assumes MAC does not strip padding or CRC.
*/
if (RecvFrameLength != 0) {
int Index;
/*
* Verify length, which should be the payload size.
*/
if ((RecvFrameLength- (XEL_HEADER_SIZE + XEL_FCS_SIZE)) !=
PayloadSize) {
return XST_LOOPBACK_ERROR;
}
/*
* Verify the contents of the Received Frame.
*/
FramePtr = (u8 *)RxFrame;
FramePtr += XEL_HEADER_SIZE; /* Get past the header */
for (Index = 0; Index < PayloadSize; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_LOOPBACK_ERROR;
}
}
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function handles the receive callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteRecvHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Receive callback.
*/
RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame);
}
/******************************************************************************/
/**
*
* This function handles the transmit callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteSendHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Transmit callback.
*/
TransmitComplete = TRUE;
}
/*****************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the EmacLite device. This function is application specific since the
* actual system may or may not have an interrupt controller. The EmacLite
* could be directly connected to a processor without an interrupt controller.
* The user should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc.
* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId)
{
int Status;
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(IntcInstancePtr,
EmacLiteIntrId,
XEmacLite_InterruptHandler,
(void *)(EmacLiteInstPtr));
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#ifndef TESTAPP_GEN
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specific real mode so that
* the EmacLite can cause interrupts thru the interrupt controller.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Enable the interrupt for the EmacLite in the Interrupt controller.
*/
XIntc_Enable(IntcInstancePtr, EmacLiteIntrId);
#ifndef TESTAPP_GEN
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XIntc_InterruptHandler,
IntcInstancePtr);
/*
* Enable non-critical exceptions.
*/
Xil_ExceptionEnable();
#endif /* TESTAPP_GEN */
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the EmacLite device.
*
* @param IntcInstancePtr is the pointer to the instance of the INTC
* component.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId)
{
/*
* Disconnect and disable the interrupts for the EmacLite device.
*/
XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId);
}

View file

@ -0,0 +1,596 @@
/******************************************************************************
*
* Copyright (C) 2009 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_phy_loopback_example.c
*
* This file contains a example for using EmacLite hardware and driver.
* This file contains an interrupt example outlining the use of interrupts and
* callbacks in the transmission/reception of Ethernet frames using MAC loop
* back in the PHY device with an incrementing payload from 1 byte to 1500 bytes
* (excluding Ethernet Header and FCS).
*
* This example assumes that there is an interrupt controller in the hardware
* system and the EmacLite device is connected to the interrupt controller.
*
* @note
*
* None
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 2.00a ktn 02/25/09 First release
* 2.01a ktn 07/20/09 Updated the example to wait for either Transmit complete
* or Rx packet reception.
* 3.00a ktn 10/22/09 Updated the example to use the HAL APIs/macros.
* Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 07/08/10 Updated example to support Little Endian MicroBlaze.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_example.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define INTC_EMACLITE_ID XPAR_INTC_0_EMACLITE_0_VEC_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int EmacLitePhyLoopbackExample(u16 DeviceId);
static int SendFrame(XEmacLite *InstancePtr, u32 PayloadSize);
static int EmacLiteRecvFrame(u32 PayloadSize);
static void EmacLiteRecvHandler(void *CallBackRef);
static void EmacLiteSendHandler(void *CallBackRef);
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId);
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId);
/************************** Variable Definitions *****************************/
XIntc IntcInstance; /* Instance of the Interrupt Controller */
/*
* Set up valid local MAC addresses. This loop back test uses the LocalAddress
* both as a source and destination MAC address.
*/
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03
};
/******************************************************************************/
/**
*
* This function is the main function of the EmacLite PHY loop back example in
* interrupt mode.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int main()
{
int Status;
/*
* Run the EmacLite PHY loop back example , specify the Device ID
* that is generated in xparameters.h.
*/
Status = EmacLitePhyLoopbackExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The main entry point for the EmacLite driver PHY loop back example in
* interrupt mode. This function will transmit/receive the frame using MAC
* interface loop back (in the PHY device) and verify the data in the received
* frame.
*
* @param DeviceId is device ID of the XEmacLite Device , typically
* XPAR_<EMACLITE_instance>_DEVICE_ID value from xparameters.h.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int EmacLitePhyLoopbackExample(u16 DeviceId)
{
int Status;
XIntc *IntcInstancePtr;
XEmacLite *EmacLiteInstPtr;
u32 PhyAddress = 0;
u32 TxLength;
XEmacLite_Config *ConfigPtr;
RecvFrameLength = 0;
IntcInstancePtr = &IntcInstance;
EmacLiteInstPtr =&EmacLiteInstance;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr, ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* If MDIO is not configured in the core then return XST_FAILURE.
*/
if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
/*
* Check if there is a Tx buffer available.
*/
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) {
return XST_FAILURE;
}
/*
* Set up the interrupt infrastructure.
*/
Status = EmacLiteSetupIntrSystem(IntcInstancePtr, EmacLiteInstPtr,
INTC_EMACLITE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the EmacLite handlers.
*/
XEmacLite_SetRecvHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteRecvHandler);
XEmacLite_SetSendHandler((EmacLiteInstPtr), (void *)(EmacLiteInstPtr),
(XEmacLite_Handler)EmacLiteSendHandler);
/*
* Enable the EmacLite interrupts.
*/
XEmacLite_EnableInterrupts(EmacLiteInstPtr);
/*
* Detect the PHY device and enable the MAC Loop back
* in the PHY.
*/
PhyAddress = EmacLitePhyDetect(EmacLiteInstPtr);
Status = EmacLiteEnablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
if (Status != XST_SUCCESS) {
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID);
return XST_FAILURE;
}
/*
* Send/Receive frames of varying sizes and verify the data in the
* received frames.
*/
for (TxLength = 1; TxLength <= XEL_MTU_SIZE; ) {
RecvFrameLength = 0;
/*
* Send a frame.
*/
Status = SendFrame(EmacLiteInstPtr, TxLength);
if (Status != XST_SUCCESS) {
/*
* Disable the MAC Loop back in the PHY and
* disable/disconnect the EmacLite Interrupts.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr,
INTC_EMACLITE_ID);
return XST_FAILURE;
}
/*
* Wait for the frame to be transmitted and received back.
* As the PHY is in loopback the transmit interrupt and the
* receive interrupt occur simulataneously.
*/
while ((TransmitComplete == FALSE) && (RecvFrameLength == 0));
/*
* Check the receive frame.
*/
Status = EmacLiteRecvFrame(TxLength++);
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) {
/*
* Disable the MAC Loop back in the PHY and
* disable/disconnect the EmacLite Interrupts.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr,
INTC_EMACLITE_ID);
return XST_FAILURE;
}
}
/*
* Disable the MAC Loop back in the PHY and
* disable/disconnect the EmacLite Interrupts.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
XEmacLite_DisableInterrupts(EmacLiteInstPtr);
EmacLiteDisableIntrSystem(IntcInstancePtr, INTC_EMACLITE_ID);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function sends a frame of given size. This function assumes interrupt
* mode and sends the frame.
*
* @param XEmacInstancePtr is a pointer to the XEmacLite instance to be
* worked on.
* @param PayloadSize is the size of the frame to create. The size only
* reflects the payload size, it does not include the Ethernet
* header size (14 bytes) nor the Ethernet CRC size (4 bytes).
* @param DestAddress if the address of the remote hardware the frame is
* to be sent to.
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int SendFrame(XEmacLite *XEmacInstancePtr, u32 PayloadSize)
{
u8 *FramePtr;
int Index;
int Status;
/*
* Set the Complete flag to false.
*/
TransmitComplete = FALSE;
/*
* Assemble the frame with a destination address and the source address.
*/
FramePtr = (u8 *)TxFrame;
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Fill in the source MAC address.
*/
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Set up the type/length field - be sure its in network order.
*/
*((u16 *)FramePtr) = Xil_Htons(PayloadSize);
FramePtr++;
FramePtr++;
/*
* Now fill in the data field with known values so we can verify them
* on receive.
*/
for (Index = 0; Index < PayloadSize; Index++) {
*FramePtr++ = (u8)Index;
}
/*
* Now send the frame.
*/
Status = XEmacLite_Send(XEmacInstancePtr, (u8 *)TxFrame,
PayloadSize + XEL_HEADER_SIZE);
return Status;
}
/******************************************************************************/
/**
*
* This function receives a frame of given size. This function assumes interrupt
* mode, receives the frame and verifies its contents.
*
* @param PayloadSize is the size of the frame to receive.
* The size only reflects the payload size, it does not include the
* Ethernet header size (14 bytes) nor the Ethernet CRC size (4
* bytes).
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int EmacLiteRecvFrame(u32 PayloadSize)
{
u8 *FramePtr;
/*
* This assumes MAC does not strip padding or CRC.
*/
if (RecvFrameLength != 0) {
int Index;
/*
* Verify length, which should be the payload size.
*/
if ((RecvFrameLength - (XEL_HEADER_SIZE + XEL_FCS_SIZE)) !=
PayloadSize) {
return XST_LOOPBACK_ERROR;
}
/*
* Verify the contents of the Received Frame.
*/
FramePtr = (u8 *)RxFrame;
FramePtr += XEL_HEADER_SIZE; /* Get past the header */
for (Index = 0; Index < PayloadSize; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_LOOPBACK_ERROR;
}
}
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function handles the receive callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteRecvHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Receive callback.
*/
RecvFrameLength = XEmacLite_Recv(XEmacInstancePtr, (u8 *)RxFrame);
}
/******************************************************************************/
/**
*
* This function handles the transmit callback from the EmacLite driver.
*
* @param CallBackRef is the call back reference provided to the Handler.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteSendHandler(void *CallBackRef)
{
XEmacLite *XEmacInstancePtr;
/*
* Convert the argument to something useful.
*/
XEmacInstancePtr = (XEmacLite *)CallBackRef;
/*
* Handle the Transmit callback.
*/
TransmitComplete = TRUE;
}
/*****************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the EmacLite device. This function is application specific since the
* actual system may or may not have an interrupt controller. The EmacLite
* could be directly connected to a processor without an interrupt controller.
* The user should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc.
* @param EmacLiteInstPtr is a pointer to the instance of the EmacLite.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h
*
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSetupIntrSystem(XIntc *IntcInstancePtr,
XEmacLite *EmacLiteInstPtr, u16 EmacLiteIntrId)
{
int Status;
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(IntcInstancePtr,
EmacLiteIntrId,
XEmacLite_InterruptHandler,
(void *)(EmacLiteInstPtr));
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#ifndef TESTAPP_GEN
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specific real mode so that
* the EmacLite can cause interrupts thru the interrupt controller.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif
/*
* Enable the interrupt for the EmacLite in the Interrupt controller.
*/
XIntc_Enable(IntcInstancePtr, EmacLiteIntrId);
#ifndef TESTAPP_GEN
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XIntc_InterruptHandler,
IntcInstancePtr);
/*
* Enable non-critical exceptions.
*/
Xil_ExceptionEnable();
#endif /* TESTAPP_GEN */
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the EmacLite device.
*
* @param IntcInstancePtr is the pointer to the instance of the INTC
* component.
* @param EmacLiteIntrId is the interrupt ID and is typically
* XPAR_<INTC_instance>_<EMACLITE_instance>_VEC_ID
* value from xparameters.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void EmacLiteDisableIntrSystem(XIntc *IntcInstancePtr,
u16 EmacLiteIntrId)
{
/*
* Disconnect and disable the interrupts for the EmacLite device.
*/
XIntc_Disconnect(IntcInstancePtr, EmacLiteIntrId);
}

View file

@ -0,0 +1,707 @@
/******************************************************************************
*
* Copyright (C) 2008 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_ping_reply_example.c
*
* This file contains an EmacLite ping reply example in polled mode. This example
* will generate a ping reply when it receives a ping request packet from the
* external world.
*
* @note
*
* The local IP address is set to 172.16.63.121. User needs to update
* LocalIpAddr variable with a free IP address based on the network on which
* this example is to be run.
*
* The local MAC address is set to 0x000A35030201. User can update LocalMacAddr
* variable with a valid MAC address. The first three bytes contains
* the manufacture ID. 0x000A35 is XILINX manufacture ID.
*
* This program will respond continuously to a number of ping requests as defined
* by MAX_PING_REPLIES in this file.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ktn 20/08/08 First release
* 3.00a ktn 10/22/09 Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 08/06/10 Updated the example to support little endian MicroBlaze.
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xemaclite.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID
/*
* Change this parameter to limit the number of ping replies sent by this
* program.
*/
#define MAX_PING_REPLIES 10 /* Maximum number of ping replies */
#define BROADCAST_PACKET 1 /* Broadcast packet */
#define MAC_MATCHED_PACKET 2 /* Dest MAC matched with local MAC */
#define IP_ADDR_SIZE 4 /* IP Address size in Bytes */
#define ARP_REQUEST 0x0001 /* ARP Request bits in Rx packet */
#define ARP_REPLY 0x0002 /* ARP status bits indicating reply */
#define ARP_PACKET_SIZE 0x3C /* ARP packet len 60 Bytes */
#define ICMP_PACKET_SIZE 0x4A /* ICMP packet length 74 Bytes
* including Src and Dest MAC Address */
#define BROADCAST_ADDR 0xFFFF /* Broadcast Address */
#define CORRECT_CKSUM_VALUE 0xFFFF /* Correct checksum value */
#define IDENT_FIELD_VALUE 0x9263 /* Identification field (random num) */
/*
* Definitions for the locations and length of some of the fields in a
* IP packet. The lengths are defined in Half-Words (2 bytes).
*/
#define ETHER_PROTO_TYPE_LEN 1 /* Ethernet protocol Type length */
#define SRC_MAC_ADDR_LOC 3 /* Source MAC address location */
#define MAC_ADDR_LEN 3 /* MAC address length */
#define ETHER_PROTO_TYPE_LOC 6 /* Ethernet Proto type location */
#define ARP_HW_TYPE_LEN 1 /* Hardware Type length */
#define ARP_PROTO_TYPE_LEN 1 /* Protocol Type length */
#define ARP_HW_ADD_LEN 1 /* Hardware address length */
#define ARP_PROTO_ADD_LEN 1 /* Protocol address length */
#define ARP_ZEROS_LEN 9 /* Length to be filled with zeros */
#define ARP_REQ_STATUS_LOC 10 /* ARP request location */
#define ARP_REQ_SRC_IP_LOC 14 /* Src IP address location of ARP request */
#define ARP_REQ_DEST_IP_LOC_1 19 /* Destination IP's 1st half word location */
#define ARP_REQ_DEST_IP_LOC_2 20 /* Destination IP's 2nd half word location */
#define IP_VERSION_LEN 1 /* IP Version length */
#define IP_PACKET_LEN 1 /* IP Packet length field */
#define IP_FRAG_FIELD_LEN 1 /* Fragment field len in ICMP packet */
#define IP_TTL_ICM_LEN 1 /* Time to live and ICM fields length */
#define IP_ADDR_LEN 2 /* Size of IP address in half-words */
#define IP_CSUM_LOC_BACK 5 /* IP checksum location from end of frame */
#define IP_HDR_START_LOC 7 /* IP header start location */
#define IP_HDR_LEN 10 /* IP Header length */
#define IP_FRAG_FIELD_LOC 10 /* Fragment field location */
#define ICMP_TYPE_LEN 1 /* ICMP Type length */
#define ICMP_ECHO_FIELD_LEN 2 /* Echo field length in half-words */
#define ICMP_REQ_SRC_IP_LOC 13 /* Src IP address location of ICMP request */
#define ICMP_ECHO_FIELD_LOC 17 /* Echo field location */
#define ICMP_DATA_START_LOC 17 /* Data field start location */
#define ICMP_DATA_LEN 18 /* ICMP data length */
#define ICMP_DATA_LOC 19 /* ICMP data location including
identifier number and sequence number */
#define ICMP_DATA_CSUM_LOC_BACK 19 /* Data checksum location from end of
frame */
#define ICMP_DATA_FIELD_LEN 20 /* Data field length */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int EmacLitePingReplyExample(u16 DeviceId);
static void ProcessRecvFrame(XEmacLite *InstancePtr);
static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length);
/************************** Variable Definitions *****************************/
/*
* Set up a local MAC address.
*/
static u8 LocalMacAddr[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x02, 0x22, 0x5E
};
/*
* The IP address was set to 172.16.63.121. User need to set a free IP address
* based on the network on which this example is to be run.
*/
static u8 LocalIpAddr[IP_ADDR_SIZE] =
{
172, 16, 63, 121
};
static XEmacLite EmacLiteInstance; /* Instance of the EmacLite driver */
/*
* Buffers used for Transmission and Reception of Packets. These are declared as
* global so that they are not a part of the stack.
*/
static u8 RxFrame[XEL_MAX_FRAME_SIZE];
static u8 TxFrame[XEL_MAX_FRAME_SIZE];
/*
* Variable used to indicate the length of the received frame.
*/
u32 RecvFrameLength = 0;
/*
* Variable used to indicate the number of Ping replies sent.
*/
u32 NumOfPingReplies;
/****************************************************************************/
/**
*
* This function is the main function of the Ping reply example in
* polled mode.
*
* @param None.
*
* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS
* is returned.
*
* @note None.
*
*****************************************************************************/
int main()
{
int Status;
/*
* Run the EmacLite Ping reply example.
*/
Status = EmacLitePingReplyExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The entry point for the EmacLite Ping reply example in polled mode.
*
* @param DeviceId is device ID of the XEmacLite Device.
*
* @return XST_FAILURE to indicate failure, otherwise XST_SUCCESS is
* returned.
*
* @note This is in a continuous loop generating a specified number of
* ping replies as defined by MAX_PING_REPLIES.
*
******************************************************************************/
int EmacLitePingReplyExample(u16 DeviceId)
{
int Status;
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance;
XEmacLite_Config *ConfigPtr;
NumOfPingReplies = 0;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalMacAddr);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
while (1) {
/*
* Wait for a Receive packet.
*/
while (RecvFrameLength == 0) {
RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr,
(u8 *)RxFrame);
}
/*
* Process the Receive frame.
*/
ProcessRecvFrame(EmacLiteInstPtr);
RecvFrameLength = 0;
/*
* If the number of ping replies sent is equal to that
* specified by the user then exit out of this loop.
*/
if (NumOfPingReplies == MAX_PING_REPLIES) {
return XST_SUCCESS;
}
}
}
/******************************************************************************/
/**
*
* This function processes the received packet and generates the corresponding
* reply packets.
*
* @param InstancePtr is a pointer to the instance of the EmacLite.
*
* @return None.
*
* @note This function assumes MAC does not strip padding or CRC.
*
******************************************************************************/
static void ProcessRecvFrame(XEmacLite *InstancePtr)
{
u16 *RxFramePtr;
u16 *TxFramePtr;
u16 *TempPtr;
u16 CheckSum;
u32 NextTxBuffBaseAddr;
int Index;
int PacketType = 0;
TxFramePtr = (u16 *)TxFrame;
RxFramePtr = (u16 *)RxFrame;
/*
* Determine the next expected Tx buffer address.
*/
NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr);
/*
* Check the packet type.
*/
Index = MAC_ADDR_LEN;
TempPtr = (u16 *)LocalMacAddr;
while (Index--) {
if (Xil_Ntohs((*(RxFramePtr + Index)) == BROADCAST_ADDR) &&
(PacketType != MAC_MATCHED_PACKET)) {
PacketType = BROADCAST_PACKET;
} else if (Xil_Ntohs((*(RxFramePtr + Index)) == *(TempPtr + Index)) &&
(PacketType != BROADCAST_PACKET)) {
PacketType = MAC_MATCHED_PACKET;
} else {
PacketType = 0;
break;
}
}
/*
* Process broadcast packet.
*/
if (PacketType == BROADCAST_PACKET) {
/*
* Check for an ARP Packet if so generate a reply.
*/
if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_ARP) {
/*
* IP address of the local machine.
*/
TempPtr = (u16 *)LocalIpAddr;
/*
* Check destination IP address of the packet with
* local IP address.
*/
if (
((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_1)) == *TempPtr++) &&
((*(RxFramePtr + ARP_REQ_DEST_IP_LOC_2)) == *TempPtr++)) {
/*
* Check ARP packet type(request/reply).
*/
if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) ==
ARP_REQUEST) {
/*
* Add destination MAC address
* to the reply packet (i.e) source
* address of the received packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Add source (local) MAC address
* to the reply packet.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}
/*
* Add Ethernet proto type H/W
* type(10/3MBps),H/W address length and
* protocol address len (i.e)same as in
* the received packet
*/
Index = ETHER_PROTO_TYPE_LOC;
while (Index < (ETHER_PROTO_TYPE_LOC +
ETHER_PROTO_TYPE_LEN +
ARP_HW_TYPE_LEN +
ARP_HW_ADD_LEN
+ ARP_PROTO_ADD_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Add ARP reply status to the reply
* packet.
*/
*TxFramePtr++ = Xil_Htons(ARP_REPLY);
/*
* Add local MAC Address
* to the reply packet.
*/
TempPtr = (u16 *)LocalMacAddr;
Index = 0;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}
/*
* Add local IP Address
* to the reply packet.
*/
TempPtr = (u16 *)LocalIpAddr;
Index = 0;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++ ;
Index++;
}
/*
* Add Destination MAC Address
* to the reply packet from the received
* packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Add Destination IP Address
* to the reply packet.
*/
Index = ARP_REQ_SRC_IP_LOC;
while (Index < (ARP_REQ_SRC_IP_LOC +
IP_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Fill zeros as per protocol.
*/
Index = 0;
while (Index < ARP_ZEROS_LEN) {
*TxFramePtr++ = 0x0000;
Index++;
}
/*
* Transmit the Reply Packet.
*/
XEmacLite_Send(InstancePtr,
(u8 *)&TxFrame,
ARP_PACKET_SIZE);
}
}
}
}
/*
* Process packets whose MAC address is matched.
*/
if (PacketType == MAC_MATCHED_PACKET) {
/*
* Check ICMP packet.
*/
if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_IP) {
/*
* Check the IP header checksum.
*/
CheckSum = CheckSumCalculation(RxFramePtr,
IP_HDR_START_LOC,
IP_HDR_LEN);
/*
* Check the Data field checksum.
*/
if (CheckSum == CORRECT_CKSUM_VALUE) {
CheckSum = CheckSumCalculation(RxFramePtr,
ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN);
if (CheckSum == CORRECT_CKSUM_VALUE) {
/*
* Add destination address
* to the reply packet (i.e)source
* address of the received packet.
*/
Index = SRC_MAC_ADDR_LOC;
while (Index < (SRC_MAC_ADDR_LOC +
MAC_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Add local MAC address
* to the reply packet.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}
/*
* Add protocol type
* header length and, packet
* length(60 Bytes) to the reply packet.
*/
Index = ETHER_PROTO_TYPE_LOC;
while (Index < (ETHER_PROTO_TYPE_LOC +
ETHER_PROTO_TYPE_LEN +
IP_VERSION_LEN +
IP_PACKET_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Identification field a random number
* which is set to IDENT_FIELD_VALUE.
*/
*TxFramePtr++ = IDENT_FIELD_VALUE;
/*
* Add fragment type, time to live and
* ICM field. It is same as in the
* received packet.
*/
Index = IP_FRAG_FIELD_LOC;
while (Index < (IP_FRAG_FIELD_LOC +
IP_TTL_ICM_LEN +
IP_FRAG_FIELD_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Checksum first set to 0 and
* added in this field later.
*/
*TxFramePtr++ = 0x0000;
/*
* Add Source IP address
*/
Index = 0;
TempPtr = (u16 *)LocalIpAddr;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *TempPtr++;
Index++;
}
/*
* Add Destination IP address.
*/
Index = ICMP_REQ_SRC_IP_LOC;
while (Index < (ICMP_REQ_SRC_IP_LOC +
IP_ADDR_LEN)) {
*TxFramePtr++ =
*(RxFramePtr + Index);
Index++;
}
/*
* Calculate checksum, and
* add it in the appropriate field.
*/
CheckSum = CheckSumCalculation(
(u16 *)TxFrame,
IP_HDR_START_LOC,
IP_HDR_LEN);
CheckSum = ~CheckSum;
*(TxFramePtr - IP_CSUM_LOC_BACK) =
Xil_Htons(CheckSum);
/*
* Echo reply status & checksum.
*/
Index = ICMP_ECHO_FIELD_LOC;
while (Index < (ICMP_ECHO_FIELD_LOC +
ICMP_ECHO_FIELD_LEN)) {
*TxFramePtr++ = 0x0000;
Index++;
}
/*
* Add data to buffer which was
* received from the packet.
*/
Index = ICMP_DATA_LOC;
while (Index < (ICMP_DATA_LOC +
ICMP_DATA_LEN)) {
*TxFramePtr++ =
(*(RxFramePtr + Index));
Index++;
}
/*
* Generate checksum for the data and
* add it in the appropriate field.
*/
CheckSum = CheckSumCalculation(
(u16 *)TxFrame,
ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN);
CheckSum = ~CheckSum;
*(TxFramePtr - ICMP_DATA_CSUM_LOC_BACK)
= Xil_Htons(CheckSum);
/*
* Transmit the frame.
*/
XEmacLite_Send(InstancePtr,
(u8 *)&TxFrame,
ICMP_PACKET_SIZE);
/*
* Increment the number of
* Ping replies sent.
*/
NumOfPingReplies++;
}
}
}
}
}
/*****************************************************************************/
/**
*
* This function calculates the checksum and returns a 16 bit result.
*
* @param RxFramePtr is a 16 bit pointer for the data to which checksum
* is to be calculated.
* @param StartLoc is the starting location of the data from which the
* checksum has to be calculated.
* @param Length is the number of halfwords(16 bits) to which checksum is
* to be calculated.
*
* @return It returns a 16 bit checksum value.
*
* @note This can also be used for calculating checksum. The ones
* complement of this return value will give the final checksum.
*
******************************************************************************/
static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length)
{
u32 Sum = 0;
u16 CheckSum = 0;
int Index;
/*
* Add all the 16 bit data.
*/
Index = StartLoc;
while (Index < (StartLoc + Length)) {
Sum = Sum + Xil_Ntohs(*(RxFramePtr + Index));
Index++;
}
/*
* Add upper 16 bits to lower 16 bits.
*/
CheckSum = Sum;
Sum = Sum >> 16;
CheckSum = Sum + CheckSum;
return CheckSum;
}

View file

@ -0,0 +1,804 @@
/******************************************************************************
*
* Copyright (C) 2008 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_ping_req_example.c
*
* This file contains a EmacLite Ping request example in polled mode. This
* example will generate a ping request for the specified IP address.
*
* @note
*
* The local IP address is set to 172.16.63.121. User needs to update
* LocalIpAddr variable with a free IP address based on the network on which
* this example is to be run.
*
* The Destination IP address is set to 172.16.63.61. User needs to update
* DestIpAddress variable with any valid IP address based on the network on which
* this example is to be run.
*
* The local MAC address is set to 0x000A35030201. User can update LocalMacAddr
* variable with a valid MAC address. The first three bytes contains
* the manufacture ID. 0x000A35 is XILINX manufacture ID.
*
* This program will generate the specified number of ping request packets as
* defined in "NUM_OF_PING_REQ_PKTS".
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ktn 27/08/08 First release
* 3.00a ktn 10/22/09 Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 08/06/10 Updated the example to support little endian MicroBlaze.
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xemaclite.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID
/*
* Change this parameter to limit the number of ping requests sent by this
* program.
*/
#define NUM_OF_PING_REQ_PKTS 100 /* Number of ping req it generates */
#define ECHO_REPLY 0x00 /* Echo reply */
#define HW_TYPE 0x01 /* Hardware type (10/100 Mbps) */
#define ARP_REQUEST 0x01 /* ARP Request bits in Rx packet */
#define ARP_REPLY 0x02 /* ARP status bits indicating reply */
#define IDEN_NUM 0x02 /* ICMP identifier number */
#define IP_VERSION 0x0604 /* IP version ipv4/ipv6 */
#define BROADCAST_ADDR 0xFFFF /* Broadcast Address */
#define CORRECT_CHECKSUM_VALUE 0xFFFF /* Correct checksum value */
#define ARP_REQ_PKT_SIZE 0x2A /* ARP request packet size */
#define ICMP_PKT_SIZE 0x4A /* ICMP packet length 74 Bytes
including Src and dest MAC Add */
#define IP_ADDR_SIZE 4 /* IP Address size in Bytes */
#define NUM_RX_PACK_CHECK_REQ 10 /* Max num of Rx pack to be checked
before sending another request */
#define NUM_PACK_CHECK_RX_PACK 100 /* Max number of pack to be checked
before to identify a Rx packet */
#define DELAY 5000000 /* Used to introduce delay */
/*
* Definitions for the locations and length of some of the fields in a
* IP packet. The lengths are defined in Half-Words (2 bytes).
*/
#define SRC_MAC_ADDR_LOC 3 /* Src MAC address location */
#define MAC_ADDR_LEN 3 /* MAC address length */
#define ETHER_PROTO_TYPE_LOC 6 /* Ethernet Proto type loc */
#define IP_ADDR_LEN 2 /* Size of IP address */
#define IP_START_LOC 7 /* IP header start location */
#define IP_HEADER_INFO_LEN 7 /* IP header information length */
#define IP_HEADER_LEN 10 /* IP header length */
#define IP_CHECKSUM_LOC 12 /* IP header checksum location */
#define IP_REQ_SRC_IP_LOC 13 /* Src IP add loc of ICMP req */
#define IP_REQ_DEST_IP_LOC 15 /* Dest IP add loc of ICMP req */
#define ICMP_KNOWN_DATA_LEN 16 /* ICMP known data length */
#define ICMP_ECHO_FIELD_LOC 17 /* Echo field loc */
#define ICMP_DATA_START_LOC 17 /* Data field start location */
#define ICMP_DATA_LEN 18 /* ICMP data length */
#define ICMP_DATA_CHECKSUM_LOC 18 /* ICMP data checksum location */
#define ICMP_IDEN_FIELD_LOC 19 /* Identifier field loc */
#define ICMP_DATA_LOC 19 /* ICMP data loc including
identifier number and sequence number */
#define ICMP_SEQ_NO_LOC 20 /* sequence number location */
#define ICMP_DATA_FIELD_LEN 20 /* Data field length */
#define ICMP_KNOWN_DATA_LOC 21 /* ICMP known data start loc */
#define ARP_REQ_STATUS_LOC 10 /* ARP request loc */
#define ARP_REQ_SRC_IP_LOC 14 /* Src IP add loc of ARP req Packet */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int EmacLitePingReqExample(u16 DeviceId);
static void SendArpReqFrame(XEmacLite *InstancePtr);
static void SendEchoReqFrame(XEmacLite *InstancePtr);
static int ProcessRecvFrame(XEmacLite *InstancePtr);
static u16 CheckSumCalculation(u16 *RxFramePtr16, int StartLoc, int Length);
static int CompareData(u16 *LhsPtr, u16 *RhsPtr, int LhsLoc, int RhsLoc,
int Count);
/************************** Variable Definitions *****************************/
/*
* Set up a local MAC address.
*/
static u8 LocalMacAddr[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x03, 0x02, 0x01
};
/*
* The IP address was set to 172.16.63.121. User need to set a free IP address
* based on the network on which this example is to be run.
*/
static u8 LocalIpAddress[IP_ADDR_SIZE] =
{
172, 16, 63, 121
};
/*
* Set up a Destination IP address. Currently it is set to 172.16.63.61.
*/
static u8 DestIpAddress[IP_ADDR_SIZE] =
{
172, 16, 63, 61
};
static u16 DestMacAddr[MAC_ADDR_LEN]; /* Destination MAC Address */
static XEmacLite EmacLiteInstance; /* Instance of the EmacLite driver */
/*
* Known data transmitted in Echo request.
*/
u16 IcmpData[ICMP_KNOWN_DATA_LEN] =
{
0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
0x7172, 0x7374, 0x7576, 0x7761, 0x6263, 0x6465, 0x6667, 0x6869
};
/*
* IP header information -- each field has its own significance.
* Icmp type, ipv4 typelength, packet length, identification field
* Fragment type, time to live and ICM, checksum.
*/
u16 IpHeaderInfo[IP_HEADER_INFO_LEN] =
{
0x0800, 0x4500, 0x003C, 0x5566, 0x0000, 0x8001, 0x0000
};
/*
* Buffers used for Transmission and Reception of Packets. These are declared as
* global so that they are not a part of the stack.
*/
static u8 RxFrame[XEL_MAX_FRAME_SIZE];
static u8 TxFrame[XEL_MAX_FRAME_SIZE];
/*
* Variable used to indicate the length of the received frame.
*/
u32 RecvFrameLength;
/*
* Variable used to indicate the sequence number of the ICMP(echo) packet.
*/
int SeqNum;
/*
* Variable used to indicate the number of ping request packets to be send.
*/
int NumOfPingReqPkts;
/****************************************************************************/
/**
*
* This function is the main function of the Ping Request example in polled mode.
*
* @param None.
*
* @return XST_FAILURE to indicate failure, otherwise it will return
* XST_SUCCESS after sending specified number of packets as
* defined in "NUM_OF_PING_REQ_PKTS" .
*
* @note None.
*
*****************************************************************************/
int main()
{
int Status;
/*
* Run the EmacLite Ping request example.
*/
Status = EmacLitePingReqExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The entry point for the EmacLite driver to ping request example in polled
* mode. This function will generate specified number of request packets as
* defined in "NUM_OF_PING_REQ_PKTS.
*
* @param DeviceId is device ID of the XEmacLite Device.
*
* @return XST_FAILURE to indicate failure, otherwise it will return
* XST_SUCCESS.
*
* @note None.
*
******************************************************************************/
static int EmacLitePingReqExample(u16 DeviceId)
{
int Status;
int Index;
int Count;
int EchoReplyStatus;
XEmacLite_Config *ConfigPtr;
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance;
SeqNum = 0;
RecvFrameLength = 0;
EchoReplyStatus = XST_FAILURE;
NumOfPingReqPkts = NUM_OF_PING_REQ_PKTS;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalMacAddr);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
while (NumOfPingReqPkts--) {
/*
* Introduce delay.
*/
Count = DELAY;
while (Count--) {
}
/*
* Send an ARP or an ICMP packet based on receive packet.
*/
if (SeqNum == 0) {
SendArpReqFrame(EmacLiteInstPtr);
} else {
SendEchoReqFrame(EmacLiteInstPtr);
}
/*
* Check next 10 packets for the correct reply.
*/
Index = NUM_RX_PACK_CHECK_REQ;
while (Index--) {
/*
* Wait for a Receive packet.
*/
Count = NUM_PACK_CHECK_RX_PACK;
while (RecvFrameLength == 0) {
RecvFrameLength = XEmacLite_Recv(
EmacLiteInstPtr,
(u8 *)RxFrame);
/*
* To avoid infinite loop when no packet is
* received.
*/
if (Count-- == 0) {
break;
}
}
/*
* Process the Receive frame.
*/
if (RecvFrameLength != 0) {
EchoReplyStatus = ProcessRecvFrame(
EmacLiteInstPtr);
}
RecvFrameLength = 0;
/*
* Comes out of loop when an echo reply packet is
* received.
*/
if (EchoReplyStatus == XST_SUCCESS) {
break;
}
}
/*
* If no echo reply packet is received, it reports
* request timed out.
*/
if (EchoReplyStatus == XST_FAILURE) {
xil_printf("Packet No: %d",
NUM_OF_PING_REQ_PKTS - NumOfPingReqPkts);
xil_printf(" Seq NO %d Request timed out\r\n",
SeqNum);
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function will send a ARP request packet.
*
* @param InstancePtr is a pointer to the instance of the EmacLite.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void SendArpReqFrame(XEmacLite *InstancePtr)
{
u16 *TempPtr;
u16 *TxFramePtr;
u32 NextTxBuffBaseAddr;
int Index;
TxFramePtr = (u16 *)TxFrame;
/*
* Determine the next expected transmit buffer base address.
*/
NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr);
/*
* Add broadcast address.
*/
Index = MAC_ADDR_LEN;
while (Index--) {
*TxFramePtr++ = BROADCAST_ADDR;
}
/*
* Add local MAC address.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *(TempPtr + Index);
Index++;
}
/*
* Add
* - Ethernet proto type.
* - Hardware Type
* - Protocol IP Type
* - IP version (IPv6/IPv4)
* - ARP Request
*/
*TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_ARP);
*TxFramePtr++ = Xil_Htons(HW_TYPE);
*TxFramePtr++ = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP);
*TxFramePtr++ = Xil_Htons(IP_VERSION);
*TxFramePtr++ = Xil_Htons(ARP_REQUEST);
/*
* Add local MAC address.
*/
Index = 0;
TempPtr = (u16 *)LocalMacAddr;
while (Index < MAC_ADDR_LEN) {
*TxFramePtr++ = *(TempPtr + Index);
Index++;
}
/*
* Add local IP address.
*/
Index = 0;
TempPtr = (u16 *)LocalIpAddress;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *(TempPtr + Index);
Index++;
}
/*
* Fills 6 bytes of information with zeros as per protocol.
*/
Index = 0;
while (Index < 3) {
*TxFramePtr++ = 0x0000;
Index++;
}
/*
* Add Destination IP address.
*/
Index = 0;
TempPtr = (u16 *)DestIpAddress;
while (Index < IP_ADDR_LEN) {
*TxFramePtr++ = *(TempPtr + Index);
Index++;
}
/*
* Transmit the Frame.
*/
XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ARP_REQ_PKT_SIZE);
}
/*****************************************************************************/
/**
*
* This function will send a Echo request packet.
*
* @param InstancePtr is a pointer to the instance of the EmacLite.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void SendEchoReqFrame(XEmacLite *InstancePtr)
{
u16 *TempPtr;
u16 *TxFramePtr;
u16 *RxFramePtr;
u16 CheckSum;
u32 NextTxBuffBaseAddr;
int Index;
TxFramePtr = (u16 *)TxFrame;
RxFramePtr = (u16 *)RxFrame;
/*
* Determine the next expected transmit buffer base address.
*/
NextTxBuffBaseAddr = XEmacLite_NextTransmitAddr(InstancePtr);
/*
* Add Destination MAC Address.
*/
Index = MAC_ADDR_LEN;
while (Index--) {
*(TxFramePtr + Index) = *(DestMacAddr + Index);
}
/*
* Add Source MAC Address.
*/
Index = MAC_ADDR_LEN;
TempPtr = (u16 *)LocalMacAddr;
while (Index--) {
*(TxFramePtr + (Index + SRC_MAC_ADDR_LOC )) =
*(TempPtr + Index);
}
/*
* Add IP header information.
*/
Index = IP_START_LOC;
while (Index--) {
*(TxFramePtr + (Index + ETHER_PROTO_TYPE_LOC )) =
Xil_Htons(*(IpHeaderInfo + Index));
}
/*
* Add Source IP address.
*/
Index = IP_ADDR_LEN;
TempPtr = (u16 *)LocalIpAddress;
while (Index--) {
*(TxFramePtr + (Index + IP_REQ_SRC_IP_LOC )) =
*(TempPtr + Index);
}
/*
* Add Destination IP address.
*/
Index = IP_ADDR_LEN;
TempPtr = (u16 *)DestIpAddress;
while (Index--) {
*(TxFramePtr + (Index + IP_REQ_DEST_IP_LOC )) =
*(TempPtr + Index);
}
/*
* Checksum is calculated for IP field and added in the frame.
*/
CheckSum = CheckSumCalculation((u16 *)TxFrame, IP_START_LOC,
IP_HEADER_LEN);
CheckSum = ~CheckSum;
*(TxFramePtr + IP_CHECKSUM_LOC) = Xil_Htons(CheckSum);
/*
* Add echo field information.
*/
*(TxFramePtr + ICMP_ECHO_FIELD_LOC) = Xil_Htons(XEL_ETHER_PROTO_TYPE_IP);
/*
* Checksum value is initialized to zeros.
*/
*(TxFramePtr + ICMP_DATA_LEN) = 0x0000;
/*
* Add identifier and sequence number to the frame.
*/
*(TxFramePtr + ICMP_IDEN_FIELD_LOC) = (IDEN_NUM);
*(TxFramePtr + (ICMP_IDEN_FIELD_LOC + 1)) = Xil_Htons((u16)(++SeqNum));
/*
* Add known data to the frame.
*/
Index = ICMP_KNOWN_DATA_LEN;
while (Index--) {
*(TxFramePtr + (Index + ICMP_KNOWN_DATA_LOC)) =
Xil_Htons(*(IcmpData + Index));
}
/*
* Checksum is calculated for Data Field and added in the frame.
*/
CheckSum = CheckSumCalculation((u16 *)TxFrame, ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN );
CheckSum = ~CheckSum;
*(TxFramePtr + ICMP_DATA_CHECKSUM_LOC) = Xil_Htons(CheckSum);
/*
* Transmit the Frame.
*/
XEmacLite_Send(InstancePtr, (u8 *)&TxFrame, ICMP_PKT_SIZE);
}
/*****************************************************************************/
/**
*
* This function will process the received packet. This function sends
* the echo request packet based on the ARP reply packet.
*
* @param InstancePtr is a pointer to the instance of the EmacLite.
*
* @return XST_SUCCESS is returned when an echo reply is received.
* Otherwise, XST_FAILURE is returned.
*
* @note This assumes MAC does not strip padding or CRC.
*
******************************************************************************/
static int ProcessRecvFrame(XEmacLite *InstancePtr)
{
u16 *RxFramePtr;
u16 *TempPtr;
u16 CheckSum;
int Index;
int Match = 0;
int DataWrong = 0;
RxFramePtr = (u16 *)RxFrame;
TempPtr = (u16 *)LocalMacAddr;
/*
* Check Dest Mac address of the packet with the LocalMac address.
*/
Match = CompareData(RxFramePtr, TempPtr, 0, 0, MAC_ADDR_LEN);
if (Match == XST_SUCCESS) {
/*
* Check ARP type.
*/
if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_ARP ) {
/*
* Check ARP status.
*/
if (Xil_Ntohs(*(RxFramePtr + ARP_REQ_STATUS_LOC)) == ARP_REPLY) {
/*
* Check destination IP address with
* packet's source IP address.
*/
TempPtr = (u16 *)DestIpAddress;
Match = CompareData(RxFramePtr,
TempPtr, ARP_REQ_SRC_IP_LOC,
0, IP_ADDR_LEN);
if (Match == XST_SUCCESS) {
/*
* Copy src Mac address of the received
* packet.
*/
Index = MAC_ADDR_LEN;
TempPtr = (u16 *)DestMacAddr;
while (Index--) {
*(TempPtr + Index) =
*(RxFramePtr +
(SRC_MAC_ADDR_LOC +
Index));
}
/*
* Send Echo request packet.
*/
SendEchoReqFrame(InstancePtr);
}
}
}
/*
* Check for IP type.
*/
else if (Xil_Ntohs(*(RxFramePtr + ETHER_PROTO_TYPE_LOC)) ==
XEL_ETHER_PROTO_TYPE_IP) {
/*
* Calculate checksum.
*/
CheckSum = CheckSumCalculation(RxFramePtr,
ICMP_DATA_START_LOC,
ICMP_DATA_FIELD_LEN);
/*
* Verify checksum, echo reply, identifier number and
* sequence number of the received packet.
*/
if ((CheckSum == CORRECT_CHECKSUM_VALUE) &&
(Xil_Ntohs(*(RxFramePtr + ICMP_ECHO_FIELD_LOC)) == ECHO_REPLY) &&
(Xil_Ntohs(*(RxFramePtr + ICMP_IDEN_FIELD_LOC)) == IDEN_NUM) &&
(Xil_Ntohs(*(RxFramePtr + (ICMP_SEQ_NO_LOC))) == SeqNum)) {
/*
* Verify data in the received packet with known
* data.
*/
TempPtr = IcmpData;
Match = CompareData(RxFramePtr,
TempPtr, ICMP_KNOWN_DATA_LOC,
0, ICMP_KNOWN_DATA_LEN);
if (Match == XST_FAILURE) {
DataWrong = 1;
}
}
if (DataWrong != 1) {
xil_printf("Packet No: %d ",
NUM_OF_PING_REQ_PKTS - NumOfPingReqPkts);
xil_printf("Seq NO %d Echo Packet received\r\n",
SeqNum);
return XST_SUCCESS;
}
}
}
return XST_FAILURE;
}
/*****************************************************************************/
/**
*
* This function calculates the checksum and returns a 16 bit result.
*
* @param RxFramePtr is a 16 bit pointer for the data to which checksum
* is to be calculated.
* @param StartLoc is the starting location of the data from which the
* checksum has to be calculated.
* @param Length is the number of halfwords(16 bits) to which checksum is
* to be calculated.
*
* @return It returns a 16 bit checksum value.
*
* @note This can also be used for calculating checksum. The ones
* complement of this return value will give the final checksum.
*
******************************************************************************/
static u16 CheckSumCalculation(u16 *RxFramePtr, int StartLoc, int Length)
{
u32 Sum = 0;
u16 CheckSum = 0;
int Index;
/*
* Add all the 16 bit data.
*/
Index = StartLoc;
while (Index < (StartLoc + Length)) {
Sum = Sum + Xil_Htons(*(RxFramePtr + Index));
Index++;
}
/*
* Add upper 16 bits to lower 16 bits.
*/
CheckSum = Sum;
Sum = Sum>>16;
CheckSum = Sum + CheckSum;
return CheckSum;
}
/*****************************************************************************/
/**
*
* This function checks the match for the specified number of half words.
*
* @param LhsPtr is a LHS entity pointer.
* @param RhsPtr is a RHS entity pointer.
* @param LhsLoc is a LHS entity location.
* @param RhsLoc is a RHS entity location.
* @param Count is the number of location which has to compared.
*
* @return XST_SUCCESS is returned when both the entities are same,
* otherwise XST_FAILURE is returned.
*
* @note None.
*
******************************************************************************/
static int CompareData(u16 *LhsPtr, u16 *RhsPtr, int LhsLoc, int RhsLoc,
int Count)
{
int Result;
while (Count--) {
if (*(LhsPtr + LhsLoc + Count) == *(RhsPtr + RhsLoc + Count)) {
Result = XST_SUCCESS;
} else {
Result = XST_FAILURE;
break;
}
}
return Result;
}

View file

@ -0,0 +1,390 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xemaclite_polled_example.c
*
* This file contains an example for using the EmacLite hardware and driver.
* This file contains an polled mode example outlining the transmission/reception
* of an Ethernet frame of 1000 bytes of payload.
*
* If the MDIO interface is NOT configured in the EmacLite core then this example
* will only transmit a frame.
* If the MDIO interface is configured in the EmacLite core then this example
* will enable the MAC loopback in the PHY device, then transmit the frame and
* compare the received frame.
*
* @note
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 21/05/04 First release
* 1.01a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines
* 2.00a ktn 02/25/09 Updated to use PHY loop back if MDIO is configured in
* core and updated to be used in Test App
* 3.00a ktn 10/22/09 Updated example to use the macros that have been changed
* in the driver to remove _m from the name of the macro.
* 3.01a ktn 07/08/10 Updated example to support Little Endian MicroBlaze.
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_example.h"
/************************** Constant Definitions *****************************/
/*
* The Size of the Test Frame.
*/
#define EMACLITE_TEST_FRAME_SIZE 1000
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int EmacLitePolledExample(u16 DeviceId);
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize);
static int EmacLiteRecvFrame(u32 PayloadSize);
/************************** Variable Definitions *****************************/
/*
* Set up valid local and remote MAC addresses. This loop back test uses the
* LocalAddress both as a source and destination MAC address.
*/
static u8 LocalAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x0A, 0x35, 0x01, 0x02, 0x03
};
static u8 RemoteAddress[XEL_MAC_ADDR_SIZE] =
{
0x00, 0x10, 0xa4, 0xb6, 0xfd, 0x09
};
/****************************************************************************/
/**
*
* This function is the main function of the EmacLite polled example.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE .
*
* @note None.
*
*****************************************************************************/
#ifndef TESTAPP_GEN
int main()
{
int Status;
/*
* Run the EmacLite Polled example, specify the Device ID that is
* generated in xparameters.h.
*/
Status = EmacLitePolledExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* The main entry point for the EmacLite driver example in polled mode.
*
* This function will transmit/receive the Ethernet frames and verify the
* data in the received frame (if the MDIO interface is configured in the
* EmacLite core).
* This function simply transmits a frame if the MDIO interface is not
* configured in the EmacLite core.
*
* @param DeviceId is device ID of the XEmacLite Device , typically
* XPAR_<EMAC_instance>_DEVICE_ID value from xparameters.h.
*
* @return XST_SUCCESS to indicate success, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
int EmacLitePolledExample(u16 DeviceId)
{
int Status;
XEmacLite *EmacLiteInstPtr = &EmacLiteInstance;
u32 PhyAddress = 0;
RecvFrameLength = 0;
XEmacLite_Config *ConfigPtr;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(EmacLiteInstPtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the MAC address.
*/
XEmacLite_SetMacAddress(EmacLiteInstPtr, LocalAddress);
/*
* Empty any existing receive frames.
*/
XEmacLite_FlushReceive(EmacLiteInstPtr);
/*
* Check if there is a TX buffer available, if there isn't it is an
* error.
*/
if (XEmacLite_TxBufferAvailable(EmacLiteInstPtr) != TRUE) {
return XST_FAILURE;
}
/*
* If the MDIO is configured in the device.
*/
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Detect the PHY device and enable the MAC Loop back
* in the PHY.
*/
PhyAddress = EmacLitePhyDetect(EmacLiteInstPtr);
Status = EmacLiteEnablePhyLoopBack(EmacLiteInstPtr,
PhyAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
}
/*
* Reset the receive frame length to zero.
*/
RecvFrameLength = 0;
Status = EmacLiteSendFrame(EmacLiteInstPtr, EMACLITE_TEST_FRAME_SIZE);
if (Status != XST_SUCCESS) {
if (XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
/*
* Disable the MAC Loop back in the PHY.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr,
PhyAddress);
return XST_FAILURE;
}
}
/*
* If the MDIO is not configured in the core then return XST_SUCCESS
* as the frame has been transmitted.
*/
if (!XEmacLite_IsMdioConfigured(EmacLiteInstPtr)) {
return XST_SUCCESS;
}
/*
* Poll for receive packet.
*/
while ((volatile u32)RecvFrameLength == 0) {
RecvFrameLength = XEmacLite_Recv(EmacLiteInstPtr,
(u8 *)RxFrame);
}
/*
* Check the received frame.
*/
Status = EmacLiteRecvFrame(EMACLITE_TEST_FRAME_SIZE);
if ((Status != XST_SUCCESS) && (Status != XST_NO_DATA)) {
/*
* Disable the MAC Loop back in the PHY.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
return XST_FAILURE;
}
/*
* Disable the MAC Loop back in the PHY.
*/
EmacLiteDisablePhyLoopBack(EmacLiteInstPtr, PhyAddress);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function sends a frame of given size.
*
* @param XEmacInstancePtr is a pointer to the XEmacLite instance.
* @param PayloadSize is the size of the frame to create. The size only
* reflects the payload size, it does not include the Ethernet
* header size (14 bytes) nor the Ethernet CRC size (4 bytes).
*
* @return XST_SUCCESS if successful, else a driver-specific return code.
*
* @note None.
*
******************************************************************************/
static int EmacLiteSendFrame(XEmacLite *InstancePtr, u32 PayloadSize)
{
u8 *FramePtr;
int Index;
FramePtr = (u8 *)TxFrame;
/*
* Set up the destination address as the local address for
* Phy Loopback.
*/
if (XEmacLite_IsMdioConfigured(InstancePtr)) {
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
} else {
/*
* Fill in the valid Destination MAC address if
* the Loopback is not enabled.
*/
*FramePtr++ = RemoteAddress[0];
*FramePtr++ = RemoteAddress[1];
*FramePtr++ = RemoteAddress[2];
*FramePtr++ = RemoteAddress[3];
*FramePtr++ = RemoteAddress[4];
*FramePtr++ = RemoteAddress[5];
}
/*
* Fill in the source MAC address.
*/
*FramePtr++ = LocalAddress[0];
*FramePtr++ = LocalAddress[1];
*FramePtr++ = LocalAddress[2];
*FramePtr++ = LocalAddress[3];
*FramePtr++ = LocalAddress[4];
*FramePtr++ = LocalAddress[5];
/*
* Set up the type/length field - be sure its in network order.
*/
*((u16 *)FramePtr) = Xil_Htons(PayloadSize);
FramePtr++;
FramePtr++;
/*
* Now fill in the data field with known values so we can verify them
* on receive.
*/
for (Index = 0; Index < PayloadSize; Index++) {
*FramePtr++ = (u8)Index;
}
/*
* Now send the frame.
*/
return XEmacLite_Send(InstancePtr, (u8 *)TxFrame,
PayloadSize + XEL_HEADER_SIZE);
}
/******************************************************************************/
/**
*
* This function receives a frame of given size. This function assumes interrupt
* mode, receives the frame and verifies its contents.
*
* @param PayloadSize is the size of the frame to receive.
* The size only reflects the payload size, it does not include the
* Ethernet header size (14 bytes) nor the Ethernet CRC size (4
* bytes).
*
* @return XST_SUCCESS if successful, a driver-specific return code if not.
*
* @note None.
*
******************************************************************************/
static int EmacLiteRecvFrame(u32 PayloadSize)
{
u8 *FramePtr;
/*
* This assumes MAC does not strip padding or CRC.
*/
if (RecvFrameLength != 0) {
int Index;
/*
* Verify length, which should be the payload size.
*/
if ((RecvFrameLength- (XEL_HEADER_SIZE + XEL_FCS_SIZE)) !=
PayloadSize) {
return XST_LOOPBACK_ERROR;
}
/*
* Verify the contents of the Received Frame.
*/
FramePtr = (u8 *)RxFrame;
FramePtr += XEL_HEADER_SIZE; /* Get past the header */
for (Index = 0; Index < PayloadSize; Index++) {
if (*FramePtr++ != (u8)Index) {
return XST_LOOPBACK_ERROR;
}
}
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,152 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xemaclite_selftest_example.c
*
* This file contains a design example using the EmacLite driver.
*
* @note
*
* None.
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 01/25/05 Initial release for TestApp integration.
* 1.00a sv 06/06/05 Minor changes to comply to Doxygen and coding guidelines
* 2.00a ktn 04/14/09 Removed support for TestApp
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xemaclite.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define EMAC_DEVICE_ID XPAR_EMACLITE_0_DEVICE_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int EMACLiteSelfTestExample(u16 DeviceId);
/************************** Variable Definitions *****************************/
/*
* Instance of the driver
*/
static XEmacLite EmacLite;
/****************************************************************************/
/**
*
* This function is the main function of the EmacLite selftest example.
*
* @param None
*
* @return XST_SUCCESS to indicate success, else XST_FAILURE.
*
* @note None
*
*****************************************************************************/
int main(void)
{
int Status;
/*
* Run the EmacLite Self test example, specify the Device ID that is
* generated in xparameters.h
*/
Status = EMACLiteSelfTestExample(EMAC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* The main entry point for the EmacLite driver selftest example.
*
* @param DeviceId is the XPAR_<xemaclite_instance>_DEVICE_ID value from
* xparameters.h
*
* @return XST_SUCCESS to indicate success, else XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int EMACLiteSelfTestExample(u16 DeviceId)
{
int Status;
XEmacLite_Config *ConfigPtr;
XEmacLite *InstancePtr = &EmacLite;
/*
* Initialize the EmacLite device.
*/
ConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XEmacLite_CfgInitialize(InstancePtr,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Run the Self Test
*/
Status = XEmacLite_SelfTest(InstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

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

View file

@ -0,0 +1,971 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* Functions in this file are the minimum required functions for the EmacLite
* driver. See xemaclite.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.01a ecm 01/31/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 1.11a ecm 05/18/07 Updated the TxBufferAvailable routine to look at both
* the active and busy bits
* 1.13a sv 02/1/08 Updated the TxBufferAvailable routine to return
* busy status properly
* 2.00a ktn 02/16/09 Added support for MDIO
* 2.01a ktn 07/20/09 Modified XEmacLite_Send function to use Ping buffers
* Interrupt enable bit since this alone is used to enable
* the interrupts for both Ping and Pong Buffers.
* 3.00a ktn 10/22/09 Updated driver to use the HAL APIs/macros.
* The macros have been renamed to remove _m from the name.
* 3.01a ktn 07/08/10 The macro XEmacLite_GetReceiveDataLength is changed to
* a static function.
* Updated the XEmacLite_GetReceiveDataLength and
* XEmacLite_Recv functions to support little endian
* MicroBlaze.
* 3.02a sdm 07/22/11 Removed redundant code in XEmacLite_Recv functions for
* CR617290
* 3.04a srt 04/13/13 Removed warnings (CR 705000).
*
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_io.h"
#include "xenv.h"
#include "xemaclite.h"
#include "xemaclite_i.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Initialize a specific XEmacLite instance/driver. The initialization entails:
* - Initialize fields of the XEmacLite instance structure.
*
* The driver defaults to polled mode operation.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param EmacLiteConfigPtr points to the XEmacLite device configuration
* structure.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. If the address translation is not used then the
* physical address is passed.
* Unexpected errors may occur if the address mapping is changed
* after this function is invoked.
*
* @return
* - XST_SUCCESS if initialization was successful.
*
* @note The initialization of the PHY device is not done in this
* function. The user needs to use XEmacLite_PhyRead and
* XEmacLite_PhyWrite functions to access the PHY device.
*
******************************************************************************/
int XEmacLite_CfgInitialize(XEmacLite *InstancePtr,
XEmacLite_Config *EmacLiteConfigPtr,
u32 EffectiveAddr)
{
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(EmacLiteConfigPtr != NULL);
/*
* Zero the provided instance memory.
*/
memset(InstancePtr, 0, sizeof(XEmacLite));
/*
* Set some default values for instance data, don't indicate the device
* is ready to use until everything has been initialized successfully.
*/
InstancePtr->EmacLiteConfig.BaseAddress = EffectiveAddr;
InstancePtr->EmacLiteConfig.DeviceId = EmacLiteConfigPtr->DeviceId;
InstancePtr->EmacLiteConfig.TxPingPong = EmacLiteConfigPtr->TxPingPong;
InstancePtr->EmacLiteConfig.RxPingPong = EmacLiteConfigPtr->RxPingPong;
InstancePtr->EmacLiteConfig.MdioInclude = EmacLiteConfigPtr->MdioInclude;
InstancePtr->EmacLiteConfig.Loopback = EmacLiteConfigPtr->Loopback;
InstancePtr->NextTxBufferToUse = 0x0;
InstancePtr->NextRxBufferToUse = 0x0;
InstancePtr->RecvHandler = (XEmacLite_Handler) StubHandler;
InstancePtr->SendHandler = (XEmacLite_Handler) StubHandler;
/*
* Clear the TX CSR's in case this is a restart.
*/
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_TSR_OFFSET, 0);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
/*
* Since there were no failures, indicate the device is ready to use.
*/
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* Send an Ethernet frame. The ByteCount is the total frame size, including
* header.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param FramePtr is a pointer to frame. For optimal performance, a
* 32-bit aligned buffer should be used but it is not required, the
* function will align the data if necessary.
* @param ByteCount is the size, in bytes, of the frame
*
* @return
* - XST_SUCCESS if data was transmitted.
* - XST_FAILURE if buffer(s) was (were) full and no valid data was
* transmitted.
*
* @note
*
* This function call is not blocking in nature, i.e. it will not wait until the
* frame is transmitted.
*
******************************************************************************/
int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount)
{
u32 Register;
u32 BaseAddress;
u32 EmacBaseAddress;
u32 IntrEnableStatus;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Determine the expected TX buffer address.
*/
BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
EmacBaseAddress = InstancePtr->EmacLiteConfig.BaseAddress;
/*
* Check the Length if it is too large, truncate it.
* The maximum Tx packet size is
* Ethernet header (14 Bytes) + Maximum MTU (1500 bytes).
*/
if (ByteCount > XEL_MAX_TX_FRAME_SIZE) {
ByteCount = XEL_MAX_TX_FRAME_SIZE;
}
/*
* Determine if the expected buffer address is empty.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
/*
* If the expected buffer is available, fill it with the provided data
* Align if necessary.
*/
if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
/*
* Switch to next buffer if configured.
*/
if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
InstancePtr->NextTxBufferToUse ^= XEL_BUFFER_OFFSET;
}
/*
* Write the frame to the buffer.
*/
XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
ByteCount);
/*
* The frame is in the buffer, now send it.
*/
XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
(ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
XEL_TPLR_LENGTH_MASK_LO)));
/*
* Update the Tx Status Register to indicate that there is a
* frame to send.
* If the interrupt enable bit of Ping buffer(since this
* controls both the buffers) is enabled then set the
* XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the interrupt
* handler to call the callback function provided by the user
* to indicate that the frame has been transmitted.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
Register |= XEL_TSR_XMIT_BUSY_MASK;
IntrEnableStatus = XEmacLite_GetTxStatus(EmacBaseAddress);
if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
Register |= XEL_TSR_XMIT_ACTIVE_MASK;
}
XEmacLite_SetTxStatus(BaseAddress, Register);
return XST_SUCCESS;
}
/*
* If the expected buffer was full, try the other buffer if configured.
*/
if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
BaseAddress ^= XEL_BUFFER_OFFSET;
/*
* Determine if the expected buffer address is empty.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
/*
* If the next buffer is available, fill it with the provided
* data.
*/
if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
/*
* Write the frame to the buffer.
*/
XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
ByteCount);
/*
* The frame is in the buffer, now send it.
*/
XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
(ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
XEL_TPLR_LENGTH_MASK_LO)));
/*
* Update the Tx Status Register to indicate that there
* is a frame to send.
* If the interrupt enable bit of Ping buffer(since this
* controls both the buffers) is enabled then set the
* XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the
* interrupt handler to call the callback function
* provided by the user to indicate that the frame has
* been transmitted.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
Register |= XEL_TSR_XMIT_BUSY_MASK;
IntrEnableStatus =
XEmacLite_GetTxStatus(EmacBaseAddress);
if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
Register |= XEL_TSR_XMIT_ACTIVE_MASK;
}
XEmacLite_SetTxStatus(BaseAddress, Register);
/*
* Do not switch to next buffer, there is a sync problem
* and the expected buffer should not change.
*/
return XST_SUCCESS;
}
}
/*
* Buffer(s) was(were) full, return failure to allow for polling usage.
*/
return XST_FAILURE;
}
/*****************************************************************************/
/**
*
* Receive a frame. Intended to be called from the interrupt context or
* with a wrapper which waits for the receive frame to be available.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param FramePtr is a pointer to a buffer where the frame will
* be stored. The buffer must be at least XEL_MAX_FRAME_SIZE bytes.
* For optimal performance, a 32-bit aligned buffer should be used
* but it is not required, the function will align the data if
* necessary.
*
* @return
*
* The type/length field of the frame received. When the type/length field
* contains the type, XEL_MAX_FRAME_SIZE bytes will be copied out of the
* buffer and it is up to the higher layers to sort out the frame.
* Function returns 0 if there is no data waiting in the receive buffer or
* the pong buffer if configured.
*
* @note
*
* This function call is not blocking in nature, i.e. it will not wait until
* a frame arrives.
*
******************************************************************************/
u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr)
{
u16 LengthType;
u16 Length;
u32 Register;
u32 BaseAddress;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Determine the expected buffer address.
*/
BaseAddress = XEmacLite_NextReceiveAddr(InstancePtr);
/*
* Verify which buffer has valid data.
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
if ((Register & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
/*
* The driver is in sync, update the next expected buffer if
* configured.
*/
if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
InstancePtr->NextRxBufferToUse ^= XEL_BUFFER_OFFSET;
}
}
else {
/*
* The instance is out of sync, try other buffer if other
* buffer is configured, return 0 otherwise. If the instance is
* out of sync, do not update the 'NextRxBufferToUse' since it
* will correct on subsequent calls.
*/
if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
BaseAddress ^= XEL_BUFFER_OFFSET;
}
else {
return 0; /* No data was available */
}
/*
* Verify that buffer has valid data.
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
if ((Register & XEL_RSR_RECV_DONE_MASK) !=
XEL_RSR_RECV_DONE_MASK) {
return 0; /* No data was available */
}
}
/*
* Get the length of the frame that arrived.
*/
LengthType = XEmacLite_GetReceiveDataLength(BaseAddress);
/*
* Check if length is valid.
*/
if (LengthType > XEL_MAX_FRAME_SIZE) {
if (LengthType == XEL_ETHER_PROTO_TYPE_IP) {
/*
* The packet is a an IP Packet.
*/
#ifdef __LITTLE_ENDIAN__
Length = (XEmacLite_ReadReg((BaseAddress),
XEL_HEADER_IP_LENGTH_OFFSET +
XEL_RXBUFF_OFFSET) &
(XEL_RPLR_LENGTH_MASK_HI |
XEL_RPLR_LENGTH_MASK_LO));
Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
#else
Length = ((XEmacLite_ReadReg((BaseAddress),
XEL_HEADER_IP_LENGTH_OFFSET +
XEL_RXBUFF_OFFSET) >>
XEL_HEADER_SHIFT) &
(XEL_RPLR_LENGTH_MASK_HI |
XEL_RPLR_LENGTH_MASK_LO));
#endif
Length += XEL_HEADER_SIZE + XEL_FCS_SIZE;
} else if (LengthType == XEL_ETHER_PROTO_TYPE_ARP) {
/*
* The packet is an ARP Packet.
*/
Length = XEL_ARP_PACKET_SIZE + XEL_HEADER_SIZE +
XEL_FCS_SIZE;
} else {
/*
* Field contains type other than IP or ARP, use max
* frame size and let user parse it.
*/
Length = XEL_MAX_FRAME_SIZE;
}
} else {
/*
* Use the length in the frame, plus the header and trailer.
*/
Length = LengthType + XEL_HEADER_SIZE + XEL_FCS_SIZE;
}
/*
* Read from the EmacLite.
*/
XEmacLite_AlignedRead(((u32 *) (BaseAddress + XEL_RXBUFF_OFFSET)),
FramePtr, Length);
/*
* Acknowledge the frame.
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
Register &= ~XEL_RSR_RECV_DONE_MASK;
XEmacLite_SetRxStatus(BaseAddress, Register);
return Length;
}
/*****************************************************************************/
/**
*
* Set the MAC address for this device. The address is a 48-bit value.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param AddressPtr is a pointer to a 6-byte MAC address.
* the format of the MAC address is major octet to minor octet
*
* @return None.
*
* @note
*
* - TX must be idle and RX should be idle for deterministic results.
* It is recommended that this function should be called after the
* initialization and before transmission of any packets from the device.
* - Function will not return if hardware is absent or not functioning
* properly.
* - The MAC address can be programmed using any of the two transmit
* buffers (if configured).
*
******************************************************************************/
void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr)
{
u32 BaseAddress;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
/*
* Determine the expected TX buffer address.
*/
BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
/*
* Copy the MAC address to the Transmit buffer.
*/
XEmacLite_AlignedWrite(AddressPtr,
(u32 *) BaseAddress,
XEL_MAC_ADDR_SIZE);
/*
* Set the length.
*/
XEmacLite_WriteReg(BaseAddress,
XEL_TPLR_OFFSET,
XEL_MAC_ADDR_SIZE);
/*
* Update the MAC address in the EmacLite.
*/
XEmacLite_SetTxStatus(BaseAddress, XEL_TSR_PROG_MAC_ADDR);
/*
* Wait for EmacLite to finish with the MAC address update.
*/
while ((XEmacLite_GetTxStatus(BaseAddress) &
XEL_TSR_PROG_MAC_ADDR) != 0);
}
/******************************************************************************/
/**
*
* This is a stub for the send and receive callbacks. The stub
* is here in case the upper layers forget to set the handlers.
*
* @param CallBackRef is a pointer to the upper layer callback reference.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void StubHandler(void *CallBackRef)
{
(void)(CallBackRef);
Xil_AssertVoidAlways();
}
/****************************************************************************/
/**
*
* Determine if there is a transmit buffer available.
*
* @param InstancePtr is the pointer to the instance of the driver to
* be worked on.
*
* @return
* - TRUE if there is a TX buffer available for data to be written
* - FALSE if Tx Buffer is not available.
*
* @note None.
*
*****************************************************************************/
int XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr)
{
u32 Register;
int TxPingBusy;
int TxPongBusy;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Read the Tx Status and determine if the buffer is available.
*/
Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
BaseAddress);
TxPingBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
XEL_TSR_XMIT_ACTIVE_MASK));
/*
* Read the Tx Status of the second buffer register and determine if the
* buffer is available.
*/
if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
BaseAddress +
XEL_BUFFER_OFFSET);
TxPongBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
XEL_TSR_XMIT_ACTIVE_MASK));
return (!(TxPingBusy && TxPongBusy));
}
return (!TxPingBusy);
}
/****************************************************************************/
/**
*
* Flush the Receive buffers. All data will be lost.
*
* @param InstancePtr is the pointer to the instance of the driver to
* be worked on.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XEmacLite_FlushReceive(XEmacLite *InstancePtr)
{
u32 Register;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
/*
* Read the current buffer register and determine if the buffer is
* available.
*/
Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
BaseAddress);
/*
* Preserve the IE bit.
*/
Register &= XEL_RSR_RECV_IE_MASK;
/*
* Write out the value to flush the RX buffer.
*/
XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress,
Register);
/*
* If the pong buffer is available, flush it also.
*/
if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
/*
* Read the current buffer register and determine if the buffer
* is available.
*/
Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
BaseAddress +
XEL_BUFFER_OFFSET);
/*
* Preserve the IE bit.
*/
Register &= XEL_RSR_RECV_IE_MASK;
/*
* Write out the value to flush the RX buffer.
*/
XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress +
XEL_BUFFER_OFFSET, Register);
}
}
/******************************************************************************/
/**
*
* Read the specified PHY register.
*
* @param InstancePtr is the pointer to the instance of the driver.
* @param PhyAddress is the address of the PHY device. The valid range is
* is from 0 to 31.
* @param RegNum is the register number in the PHY device which
* is to be read. The valid range is is from 0 to 31.
* @param PhyDataPtr is a pointer to the data in which the data read
* from the PHY device is returned.
*
* @return
* - XST_SUCCESS if the data is read from the PHY.
* - XST_DEVICE_BUSY if MDIO is busy.
*
* @note This function waits for the completion of MDIO data transfer.
*
*****************************************************************************/
int XEmacLite_PhyRead(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
u16 *PhyDataPtr)
{
u32 PhyAddrReg;
u32 MdioCtrlReg;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
Xil_AssertNonvoid(PhyAddress <= 31);
Xil_AssertNonvoid(RegNum <= 31);
Xil_AssertNonvoid(PhyDataPtr != NULL);
/*
* Verify MDIO master status.
*/
if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET) &
XEL_MDIOCNTR_STATUS_MASK) {
return XST_DEVICE_BUSY;
}
PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
XEL_MDIO_ADDRESS_MASK) | RegNum) | XEL_MDIO_OP_MASK);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOADDR_OFFSET, PhyAddrReg);
/*
* Enable MDIO and start the transfer.
*/
MdioCtrlReg =
XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET,
MdioCtrlReg |
XEL_MDIOCNTR_STATUS_MASK |
XEL_MDIOCNTR_ENABLE_MASK);
/*
* Wait till the completion of transfer.
*/
while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET) &
XEL_MDIOCNTR_STATUS_MASK));
/*
* Read data from MDIO read data register.
*/
*PhyDataPtr = (u16)XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIORD_OFFSET);
/*
* Disable the MDIO.
*/
MdioCtrlReg =
XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET,
MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* Write the given data to the specified register in the PHY device.
*
* @param InstancePtr is the pointer to the instance of the driver.
* @param PhyAddress is the address of the PHY device. The valid range is
* is from 0 to 31.
* @param RegNum is the register number in the PHY device which
* is to be written. The valid range is is from 0 to 31.
* @param PhyData is the data to be written to the specified register in
* the PHY device.
*
* @return
* - XST_SUCCESS if the data is written to the PHY.
* - XST_DEVICE_BUSY if MDIO is busy.
*
* @note This function waits for the completion of MDIO data transfer.
*
*******************************************************************************/
int XEmacLite_PhyWrite(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
u16 PhyData)
{
u32 PhyAddrReg;
u32 MdioCtrlReg;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
Xil_AssertNonvoid(PhyAddress <= 31);
Xil_AssertNonvoid(RegNum <= 31);
/*
* Verify MDIO master status.
*/
if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET) &
XEL_MDIOCNTR_STATUS_MASK) {
return XST_DEVICE_BUSY;
}
PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
XEL_MDIO_ADDRESS_MASK) | RegNum) & ~XEL_MDIO_OP_MASK);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOADDR_OFFSET, PhyAddrReg);
/*
* Write data to MDIO write data register.
*/
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOWR_OFFSET, (u32)PhyData);
/*
* Enable MDIO and start the transfer.
*/
MdioCtrlReg =
XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET,
MdioCtrlReg | XEL_MDIOCNTR_STATUS_MASK |
XEL_MDIOCNTR_ENABLE_MASK);
/*
* Wait till the completion of transfer.
*/
while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET) & XEL_MDIOCNTR_STATUS_MASK));
/*
* Disable the MDIO.
*/
MdioCtrlReg =
XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_MDIOCNTR_OFFSET,
MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* Enable Internal loop back functionality.
*
* @param InstancePtr is the pointer to the instance of the driver.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XEmacLite_EnableLoopBack(XEmacLite *InstancePtr)
{
u32 TsrReg;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_TSR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_TSR_OFFSET, TsrReg | XEL_TSR_LOOPBACK_MASK);
}
/****************************************************************************/
/**
*
* Disable Internal loop back functionality.
*
* @param InstancePtr is the pointer to the instance of the driver.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XEmacLite_DisableLoopBack(XEmacLite *InstancePtr)
{
u32 TsrReg;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_TSR_OFFSET);
XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
XEL_TSR_OFFSET, TsrReg & (~XEL_TSR_LOOPBACK_MASK));
}
/*****************************************************************************/
/**
*
* Return the length of the data in the Receive Buffer.
*
* @param BaseAddress contains the base address of the device.
*
* @return The type/length field of the frame received.
*
* @note None.
*
******************************************************************************/
static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress)
{
u16 Length;
#ifdef __LITTLE_ENDIAN__
Length = (XEmacLite_ReadReg((BaseAddress),
XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) &
(XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));
Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
#else
Length = ((XEmacLite_ReadReg((BaseAddress),
XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) >>
XEL_HEADER_SHIFT) &
(XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));
#endif
return Length;
}
/** @} */

View file

@ -0,0 +1,408 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite.h
* @addtogroup emaclite_v4_0
* @{
* @details
*
* The Xilinx Ethernet Lite (EmacLite) driver. This driver supports the Xilinx
* Ethernet Lite 10/100 MAC (EmacLite).
*
* The Xilinx Ethernet Lite 10/100 MAC supports the following features:
* - Media Independent Interface (MII) for connection to external
* 10/100 Mbps PHY transceivers
* - Independent internal transmit and receive buffers
* - CSMA/CD compliant operations for half-duplex modes
* - Unicast and broadcast
* - Automatic FCS insertion
* - Automatic pad insertion on transmit
* - Configurable ping/pong buffers for either/both transmit and receive
* buffer areas
* - Interrupt driven mode
* - Internal loop back
* - MDIO Support to access PHY Registers
*
* The Xilinx Ethernet Lite 10/100 MAC does not support the following features:
* - multi-frame buffering
* only 1 transmit frame is allowed into each transmit buffer,
* only 1 receive frame is allowed into each receive buffer.
* the hardware blocks reception until buffer is emptied
* - Pause frame (flow control) detection in full-duplex mode
* - Programmable inter frame gap
* - Multicast and promiscuous address filtering
* - Automatic source address insertion or overwrite
*
* <b>Driver Description</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the EmacLite. The driver handles transmission and reception
* of Ethernet frames, as well as configuration of the controller. It does not
* handle protocol stack functionality such as Link Layer Control (LLC) or the
* Address Resolution Protocol (ARP). The protocol stack that makes use of the
* driver handles this functionality. This implies that the driver is simply a
* pass-through mechanism between a protocol stack and the EmacLite.
*
* Since the driver is a simple pass-through mechanism between a protocol stack
* and the EmacLite, no assembly or disassembly of Ethernet frames is done at
* the driver-level. This assumes that the protocol stack passes a correctly
* formatted Ethernet frame to the driver for transmission, and that the driver
* does not validate the contents of an incoming frame. A single device driver
* can support multiple EmacLite devices.
*
* The driver supports interrupt driven mode and the default mode of operation
* is polled mode. If interrupts are desired, XEmacLite_InterruptEnable() must
* be called.
*
* <b>Device Configuration</b>
*
* The device can be configured in various ways during the FPGA implementation
* process. Configuration parameters are stored in the xemaclite_g.c file.
* A table is defined where each entry contains configuration information for an
* EmacLite device. This information includes such things as the base address
* of the memory-mapped device and the number of buffers.
*
* <b>Interrupt Processing</b>
*
* After _Initialize is called, _InterruptEnable can be called to enable the
* interrupt driven functionality. If polled operation is desired, just call
* _Send and check the return code. If XST_FAILURE is returned, call _Send with
* the same data until XST_SUCCESS is returned. The same idea applies to _Recv.
* Call _Recv until the returned length is non-zero at which point the received
* data is in the buffer provided in the function call.
*
* The Transmit and Receive interrupts are enabled within the _InterruptEnable
* function and disabled in the _InterruptDisable function. The _Send and _Recv
* functions acknowledge the EmacLite generated interrupts associated with each
* function.
* It is the application's responsibility to acknowledge any associated Interrupt
* Controller interrupts if it is used in the system.
*
* <b>Memory Buffer Alignment</b>
*
* The alignment of the input/output buffers for the _Send and _Recv routine is
* not required to be 32 bits. If the buffer is not aligned on a 32-bit boundary
* there will be a performance impact while the driver aligns the data for
* transmission or upon reception.
*
* For optimum performance, the user should provide a 32-bit aligned buffer
* to the _Send and _Recv routines.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that application developers leave asserts on during
* development.
*
* @note
*
* This driver requires EmacLite hardware version 1.01a and higher. It is not
* compatible with earlier versions of the EmacLite hardware. Use version 1.00a
* software driver for hardware version 1.00a/b.
*
* The RX hardware is enabled from powerup and there is no disable. It is
* possible that frames have been received prior to the initialization
* of the driver. If this situation is possible, call XEmacLite_FlushReceive()
* to empty the receive buffers after initialization.
*
* This driver is intended to be RTOS and processor independent. It works
* with physical addresses only. Any needs for dynamic memory management,
* threads or thread mutual exclusion, virtual memory, or cache control must
* be satisfied by the layer above this driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 01/30/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 1.12a mta 11/28/07 Added the function XEmacLite_CfgInitialize,
* moved the functions XEmacLite_LookupConfig and
* XEmacLite_Initialize to xemaclite_sinit.c for removing
* the dependency on the static config table and
* xparameters.h from the driver initialization
* 1.13a sv 02/1/08 Updated the TxBufferAvailable routine to return
* busy status properly and added macros for Tx/Rx status
* 1.14a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
* file
* 2.00a ktn 02/16/09 Added support for MDIO and internal loop back
* 2.01a ktn 07/20/09 Updated the XEmacLite_AlignedWrite and
* XEmacLite_AlignedRead functions to use volatile
* variables so that they are not optimized.
* Modified the XEmacLite_EnableInterrupts and
* XEmacLite_DisableInterrupts functions to enable/disable
* the interrupt in the Ping buffer as this is used to enable
* the interrupts for both Ping and Pong Buffers.
* The interrupt enable bit in the Pong buffer is not used by
* the HW.
* Modified XEmacLite_Send function to use Ping buffers
* Interrupt enable bit since this alone is used to enable
* the interrupts for both Ping and Pong Buffers.
* 3.00a ktn 10/22/09 Updated driver to use the HAL Processor APIs/macros.
* The macros have been renamed to remove _m from the name in
* all the driver files.
* The macros changed in this file are
* XEmacLite_mNextTransmitAddr is XEmacLite_NextTransmitAddr,
* XEmacLite_mNextReceiveAddr is XEmacLite_NextReceiveAddr,
* XEmacLite_mIsMdioConfigured is XEmacLite_IsMdioConfigured,
* XEmacLite_mIsLoopbackConfigured is
* XEmacLite_IsLoopbackConfigured.
* See xemaclite_i.h for the macros which have changed.
* 3.01a ktn 07/08/10 The macro XEmacLite_GetReceiveDataLength in the
* xemaclite.c file is changed to a static function.
* XEmacLite_GetReceiveDataLength and XEmacLite_Recv
* functions are updated to support little endian
* MicroBlaze.
* 3.02a sdm 07/22/11 Removed redundant code in XEmacLite_Recv functions for
* CR617290
* 3.03a asa 04/05/12 Defined the flag __LITTLE_ENDIAN__ for cases where the
* driver is compiled with ARM toolchain.
* 3.04a srt 04/13/13 Removed warnings (CR 705000).
* 4.0 adk 19/12/13 Updated as per the New Tcl API's
*
* </pre>
*
*
******************************************************************************/
#ifndef XEMACLITE_H /* prevent circular inclusions */
#define XEMACLITE_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xenv.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xemaclite_l.h"
#ifdef __ARMEL__
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#endif
/************************** Constant Definitions *****************************/
/*
* Device information
*/
#define XEL_DEVICE_NAME "xemaclite"
#define XEL_DEVICE_DESC "Xilinx Ethernet Lite 10/100 MAC"
/**************************** Type Definitions *******************************/
/**
* This typedef contains configuration information for a device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Device base address */
u8 TxPingPong; /**< 1 if TX Pong buffer configured, 0 otherwise */
u8 RxPingPong; /**< 1 if RX Pong buffer configured, 0 otherwise */
u8 MdioInclude; /**< 1 if MDIO is enabled, 0 otherwise */
u8 Loopback; /**< 1 if internal loopback is enabled, 0 otherwise */
} XEmacLite_Config;
/*
* Callback when data is sent or received .
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
*/
typedef void (*XEmacLite_Handler) (void *CallBackRef);
/**
* The XEmacLite driver instance data. The user is required to allocate a
* variable of this type for every EmacLite device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XEmacLite_Config EmacLiteConfig; /* Device configuration */
u32 IsReady; /* Device is initialized and ready */
u32 NextTxBufferToUse; /* Next TX buffer to write to */
u32 NextRxBufferToUse; /* Next RX buffer to read from */
/*
* Callbacks
*/
XEmacLite_Handler RecvHandler;
void *RecvRef;
XEmacLite_Handler SendHandler;
void *SendRef;
} XEmacLite;
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* Return the next expected Transmit Buffer's address.
*
* @param InstancePtr is the pointer to the instance of the driver to
* be worked on
*
* @note C-Style signature:
* u32 XEmacLite_NextTransmitAddr(XEmacLite *InstancePtr);
*
* This macro returns the address of the next transmit buffer to put data into.
* This is used to determine the destination of the next transmit data frame.
*
*****************************************************************************/
#define XEmacLite_NextTransmitAddr(InstancePtr) \
((InstancePtr)->EmacLiteConfig.BaseAddress + \
(InstancePtr)->NextTxBufferToUse) + XEL_TXBUFF_OFFSET
/****************************************************************************/
/**
*
* Return the next expected Receive Buffer's address.
*
* @param InstancePtr is the pointer to the instance of the driver to
* be worked on
*
* @note C-Style signature:
* u32 XEmacLite_NextReceiveAddr(XEmacLite *InstancePtr);
*
* This macro returns the address of the next receive buffer to read data from.
* This is the expected receive buffer address if the driver is in sync.
*
*****************************************************************************/
#define XEmacLite_NextReceiveAddr(InstancePtr) \
((InstancePtr)->EmacLiteConfig.BaseAddress + \
(InstancePtr)->NextRxBufferToUse)
/*****************************************************************************/
/**
*
* This macro determines if the device is currently configured for MDIO.
*
* @param InstancePtr is the pointer to the instance of the
* EmacLite driver.
*
* @return
* - TRUE if the device is configured for MDIO.
* - FALSE if the device is NOT configured for MDIO.
*
* @note C-Style signature:
* int XEmacLite_IsMdioConfigured(XEmacLite *InstancePtr)
*
******************************************************************************/
#define XEmacLite_IsMdioConfigured(InstancePtr) \
((InstancePtr)->EmacLiteConfig.MdioInclude == 1)
/*****************************************************************************/
/**
*
* This macro determines if the device is currently configured for internal
* loopback.
*
* @param InstancePtr is the pointer to the instance of the
* EmacLite driver.
*
* @return
* - TRUE if the device is configured for internal loopback.
* - FALSE if the device is NOT configured for internal loopback.
*
* @note C-Style signature:
* int XEmacLite_IsLoopbackConfigured(XEmacLite *InstancePtr)
*
******************************************************************************/
#define XEmacLite_IsLoopbackConfigured(InstancePtr) \
((InstancePtr)->EmacLiteConfig.Loopback == 1)
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/*
* Functions in xemaclite.c
*/
int XEmacLite_CfgInitialize(XEmacLite *InstancePtr,
XEmacLite_Config *EmacLiteConfigPtr,
u32 EffectiveAddr);
void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr);
int XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr);
void XEmacLite_FlushReceive(XEmacLite *InstancePtr);
int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount);
u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr);
int XEmacLite_PhyRead(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
u16 *PhyDataPtr);
int XEmacLite_PhyWrite(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
u16 PhyData);
void XEmacLite_EnableLoopBack(XEmacLite *InstancePtr);
void XEmacLite_DisableLoopBack(XEmacLite *InstancePtr);
/*
* Initialization functions in xemaclite_sinit.c
*/
XEmacLite_Config *XEmacLite_LookupConfig(u16 DeviceId);
int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId);
/*
* Interrupt driven functions in xemaclite_intr.c
*/
int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr);
void XEmacLite_DisableInterrupts(XEmacLite *InstancePtr);
void XEmacLite_InterruptHandler(void *InstancePtr);
void XEmacLite_SetRecvHandler(XEmacLite *InstancePtr, void *CallBackRef,
XEmacLite_Handler FuncPtr);
void XEmacLite_SetSendHandler(XEmacLite *InstancePtr, void *CallBackRef,
XEmacLite_Handler FuncPtr);
/*
* Selftest function in xemaclite_selftest.c
*/
int XEmacLite_SelfTest(XEmacLite *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,85 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_g.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* This file contains a configuration table that specifies the configuration
* of EmacLite devices in the system.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 02/16/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 2.00a ktn 02/16/09 Added support for MDIO
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xemaclite.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Prototypes ******************************/
/**
* This table contains configuration information for each EmacLite device
* in the system.
*/
XEmacLite_Config XEmacLite_ConfigTable[XPAR_XEMACLITE_NUM_INSTANCES] = {
{
XPAR_EMACLITE_0_DEVICE_ID, /* Unique ID of device */
XPAR_EMACLITE_0_BASEADDR, /* Device base address */
XPAR_EMACLITE_0_TX_PING_PONG, /* Include TX Ping Pong buffers */
XPAR_EMACLITE_0_RX_PING_PONG, /* Include RX Ping Pong buffers */
XPAR_EMACLITE_0_INCLUDE_MDIO /* Include MDIO support */
XPAR_EMACLITE_0_INCLUDE_INTERNAL_LOOPBACK /* Include Internal
* loop back support */
}
};
/** @} */

View file

@ -0,0 +1,140 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
* @file xemaclite_i.h
* @addtogroup emaclite_v4_0
* @{
* @details
*
* This header file contains internal identifiers, which are those shared
* between the files of the driver. It is intended for internal use only.
*
* NOTES:
*
* None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.01a ecm 05/21/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 1.13a sv 02/1/08 Added macros to Get/Set Tx/Rx status
* 3.00a ktn 10/22/09 The macros have been renamed to remove _m from the name.
* The macros changed in this file are
* XEmacLite_mGetTxActive changed to XEmacLite_GetTxActive,
* XEmacLite_mSetTxActive changed to XEmacLite_SetTxActive.
*
* </pre>
******************************************************************************/
#ifndef XEMACLITE_I_H /* prevent circular inclusions */
#define XEMACLITE_I_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xemaclite.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* Get the TX active location to check status. This is used to check if
* the TX buffer is currently active. There isn't any way in the hardware
* to implement this but the register is fully populated so the driver can
* set the bit in the send routine and the ISR can clear the bit when
* the handler is complete. This mimics the correct operation of the hardware
* if it was possible to do this in hardware.
*
* @param BaseAddress is the base address of the device
*
* @return Contents of active bit in register.
*
* @note C-Style signature:
* u32 XEmacLite_GetTxActive(u32 BaseAddress)
*
*****************************************************************************/
#define XEmacLite_GetTxActive(BaseAddress) \
(XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET))
/****************************************************************************/
/**
*
* Set the TX active location to update status. This is used to set the bit
* indicating which TX buffer is currently active. There isn't any way in the
* hardware to implement this but the register is fully populated so the driver
* can set the bit in the send routine and the ISR can clear the bit when
* the handler is complete. This mimics the correct operation of the hardware
* if it was possible to do this in hardware.
*
* @param BaseAddress is the base address of the device
* @param Mask is the data to be written
*
* @return None
*
* @note C-Style signature:
* void XEmacLite_SetTxActive(u32 BaseAddress, u32 Mask)
*
*****************************************************************************/
#define XEmacLite_SetTxActive(BaseAddress, Mask) \
(XEmacLite_WriteReg((BaseAddress), XEL_TSR_OFFSET, (Mask)))
/************************** Variable Definitions ****************************/
extern XEmacLite_Config XEmacLite_ConfigTable[];
/************************** Function Prototypes ******************************/
void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount);
void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount);
void StubHandler(void *CallBackRef);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,363 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_intr.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* Functions in this file are for the interrupt driven processing functionality.
* See xemaclite.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.01a ecm 03/31/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 2.01a ktn 07/20/09 Modified the XEmacLite_EnableInterrupts and
* XEmacLite_DisableInterrupts functions to enable/disable
* the interrupt in the Ping buffer as this is used to enable
* the interrupts for both Ping and Pong Buffers.
* The interrupt enable bit in the Pong buffer is not used by
* the HW.
* 3.00a ktn 10/22/09 Updated file to use the HAL Processor APIs/macros.
* The macros have been renamed to remove _m from the name.
*
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemaclite_i.h"
#include "xil_io.h"
#include "xemaclite.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Enable the EmacLite Interrupts.
*
* This function must be called before other functions to send or receive data
* in interrupt driven mode. The user should have connected the
* interrupt handler of the driver to an interrupt source such as an interrupt
* controller or the processor interrupt prior to this function being called.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
*
* @return
* - XST_SUCCESS if the device interrupts were enabled
* successfully.
* - XST_NO_CALLBACK if the callbacks were not set.
*
* @note None.
*
******************************************************************************/
int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr)
{
u32 Register;
u32 BaseAddress;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress;
/*
* Verify that the handlers are in place.
*/
if ((InstancePtr->RecvHandler == (XEmacLite_Handler) StubHandler) ||
(InstancePtr->SendHandler == (XEmacLite_Handler) StubHandler)) {
return XST_NO_CALLBACK;
}
/*
* Enable the TX interrupts for both the buffers, the Interrupt Enable
* is common for the both the buffers and is defined in the
* Ping buffer.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
Register |= XEL_TSR_XMIT_IE_MASK;
XEmacLite_SetTxStatus(BaseAddress, Register);
/*
* Enable the RX interrupts for both the buffers, the Interrupt Enable
* is common for the both the buffers and is defined in the
* Ping buffer.
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
Register |= XEL_RSR_RECV_IE_MASK;
XEmacLite_SetRxStatus(BaseAddress, Register);
/*
* Enable the global interrupt output.
*/
XEmacLite_WriteReg(BaseAddress, XEL_GIER_OFFSET, XEL_GIER_GIE_MASK);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* Disables the interrupts from the device (the higher layer software is
* responsible for disabling interrupts at the interrupt controller).
*
* To start using the device again, _EnableInterrupts must be called.
*
* @param InstancePtr is a pointer to the XEmacLite instance .
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEmacLite_DisableInterrupts(XEmacLite *InstancePtr)
{
u32 Register;
u32 BaseAddress;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress;
/*
* Disable the global interrupt output.
*/
XEmacLite_WriteReg(BaseAddress, XEL_GIER_OFFSET, 0);
/*
* Disable the TX interrupts for both the buffers, the Interrupt Enable
* is common for the both the buffers and is defined in the
* Ping buffer.
*/
Register = XEmacLite_GetTxStatus(BaseAddress);
Register &= ~XEL_TSR_XMIT_IE_MASK;
XEmacLite_SetTxStatus(BaseAddress, Register);
/*
* Disable the RX interrupts for both the buffers, the Interrupt Enable
* is common for the both the buffers and is defined in the
* Ping buffer.
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
Register &= ~XEL_RSR_RECV_IE_MASK;
XEmacLite_SetRxStatus(BaseAddress, Register);
}
/*****************************************************************************/
/**
*
* Interrupt handler for the EmacLite driver. It performs the following
* processing:
*
* - Get the interrupt status from the registers to determine the source
* of the interrupt.
* - Call the appropriate handler based on the source of the interrupt.
*
* @param InstancePtr contains a pointer to the EmacLite device instance
* for the interrupt.
*
* @return None.
*
* @note None.
*
*
******************************************************************************/
void XEmacLite_InterruptHandler(void *InstancePtr)
{
XEmacLite *EmacLitePtr;
int TxCompleteIntr = FALSE;
u32 BaseAddress;
u32 TxStatus;
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertVoid(InstancePtr != NULL);
/*
* Convert the non-typed pointer to an EmacLite instance pointer
* such that there is access to the device.
*/
EmacLitePtr = (XEmacLite *) InstancePtr;
BaseAddress = EmacLitePtr->EmacLiteConfig.BaseAddress;
if ((XEmacLite_IsRxEmpty(BaseAddress) != TRUE) ||
(XEmacLite_IsRxEmpty(BaseAddress +
XEL_BUFFER_OFFSET) != TRUE)) {
/*
* Call the RX callback.
*/
EmacLitePtr->RecvHandler(EmacLitePtr->RecvRef);
}
TxStatus = XEmacLite_GetTxStatus(BaseAddress);
if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
(TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
/*
* Clear the Tx Active bit in the Tx Status Register.
*/
TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK;
XEmacLite_SetTxStatus(BaseAddress, TxStatus);
/*
* Update the flag indicating that there was a Tx Interrupt.
*/
TxCompleteIntr = TRUE;
}
TxStatus = XEmacLite_GetTxStatus(BaseAddress + XEL_BUFFER_OFFSET);
if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
(TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
/*
* Clear the Tx Active bit in the Tx Status Register.
*/
TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK;
XEmacLite_SetTxStatus(BaseAddress + XEL_BUFFER_OFFSET,
TxStatus);
/*
* Update the flag indicating that there was a Tx Interrupt.
*/
TxCompleteIntr = TRUE;
}
/*
* If there was a TX interrupt, call the callback.
*/
if (TxCompleteIntr == TRUE) {
/*
* Call the TX callback.
*/
EmacLitePtr->SendHandler(EmacLitePtr->SendRef);
}
}
/*****************************************************************************/
/**
*
* Sets the callback function for handling received frames in interrupt mode.
* The upper layer software should call this function during initialization.
* The callback is called when a frame is received. The callback function
* should communicate the data to a thread such that the processing is not
* performed in an interrupt context.
*
* The callback is invoked by the driver within interrupt context, so it needs
* to do its job quickly. If there are other potentially slow operations
* within the callback, these should be done at task-level.
*
* @param InstancePtr is a pointer to the XEmacLite instance..
* @param CallBackRef is a reference pointer to be passed back to the
* application in the callback. This helps the application
* correlate the callback to a particular driver.
* @param FuncPtr is the pointer to the callback function.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEmacLite_SetRecvHandler(XEmacLite *InstancePtr, void *CallBackRef,
XEmacLite_Handler FuncPtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->RecvHandler = FuncPtr;
InstancePtr->RecvRef = CallBackRef;
}
/*****************************************************************************/
/**
*
* Sets the callback function for handling transmitted frames in interrupt mode.
* The upper layer software should call this function during initialization.
* The callback is called when a frame is transmitted. The callback function
* should communicate the data to a thread such that the processing is not
* performed in an interrupt context.
*
* The callback is invoked by the driver within interrupt context, so it needs
* to do its job quickly. If there are other potentially slow operations
* within the callback, these should be done at task-level.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param CallBackRef is a reference pointer to be passed back to the
* application in the callback. This helps the application
* correlate the callback to a particular driver.
* @param FuncPtr is the pointer to the callback function.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEmacLite_SetSendHandler(XEmacLite *InstancePtr, void *CallBackRef,
XEmacLite_Handler FuncPtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->SendHandler = FuncPtr;
InstancePtr->SendRef = CallBackRef;
}
/** @} */

View file

@ -0,0 +1,507 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_l.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* This file contains the minimal, polled functions to send and receive Ethernet
* frames.
*
* Refer to xemaclite.h for more details.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 06/01/02 First release
* 1.01a ecm 03/31/04 Additional functionality and the _AlignedRead and
* _AlignedWrite functions.
* 1.11a mta 03/21/07 Updated to new coding style
* 2.01a ktn 07/20/09 Updated the XEmacLite_AlignedWrite and
* XEmacLite_AlignedRead functions to use volatile
* variables so that they are not optimized.
* 3.00a ktn 10/22/09 The macros have been renamed to remove _m from the name.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xemaclite_l.h"
#include "xemaclite_i.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount);
void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Send an Ethernet frame. The size is the total frame size, including header.
* This function blocks waiting for the frame to be transmitted.
*
* @param BaseAddress is the base address of the device
* @param FramePtr is a pointer to frame
* @param ByteCount is the size, in bytes, of the frame
*
* @return None.
*
* @note
*
* This function call is blocking in nature, i.e. it will wait until the
* frame is transmitted. This function can hang and not exit if the
* hardware is not configured properly.
*
* If the ping buffer is the destination of the data, the argument should be
* DeviceAddress + XEL_TXBUFF_OFFSET.
* If the pong buffer is the destination of the data, the argument should be
* DeviceAddress + XEL_TXBUFF_OFFSET + XEL_BUFFER_OFFSET.
* The function does not take the different buffers into consideration.
*
******************************************************************************/
void XEmacLite_SendFrame(u32 BaseAddress, u8 *FramePtr, unsigned ByteCount)
{
u32 Register;
/*
* Write data to the EmacLite
*/
XEmacLite_AlignedWrite(FramePtr, (u32 *) (BaseAddress), ByteCount);
/*
* The frame is in the buffer, now send it
*/
XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
(ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
XEL_TPLR_LENGTH_MASK_LO)));
Register = XEmacLite_GetTxStatus(BaseAddress);
XEmacLite_SetTxStatus(BaseAddress, Register | XEL_TSR_XMIT_BUSY_MASK);
/*
* Loop on the status waiting for the transmit to be complete.
*/
while (!XEmacLite_IsTxDone(BaseAddress));
}
/*****************************************************************************/
/**
*
* Receive a frame. Wait for a frame to arrive.
*
* @param BaseAddress is the base address of the device
* @param FramePtr is a pointer to a buffer where the frame will
* be stored.
*
* @return
*
* The type/length field of the frame received. When the type/length field
* contains the type , XEL_MAX_FRAME_SIZE bytes will be copied out of the
* buffer and it is up to the higher layers to sort out the frame.
*
* @note
*
* This function call is blocking in nature, i.e. it will wait until a
* frame arrives.
*
* If the ping buffer is the source of the data, the argument should be
* DeviceAddress + XEL_RXBUFF_OFFSET.
* If the pong buffer is the source of the data, the argument should be
* DeviceAddress + XEL_RXBUFF_OFFSET + XEL_BUFFER_OFFSET.
* The function does not take the different buffers into consideration.
*
******************************************************************************/
u16 XEmacLite_RecvFrame(u32 BaseAddress, u8 *FramePtr)
{
u16 LengthType;
u16 Length;
u32 Register;
/*
* Wait for a frame to arrive - this is a blocking call
*/
while (XEmacLite_IsRxEmpty(BaseAddress));
/*
* Get the length of the frame that arrived, only 32-bit reads are
* allowed LengthType is in the upper half of the 32-bit word.
*/
Register = XEmacLite_ReadReg(BaseAddress, XEL_RPLR_OFFSET);
LengthType = (u16) ((Register >> 16) &
(XEL_RPLR_LENGTH_MASK_HI |
XEL_RPLR_LENGTH_MASK_LO));
/*
* Check if length is valid
*/
if (LengthType > XEL_MAX_FRAME_SIZE) {
/*
* Field contain type, use max frame size and
* let user parse it
*/
Length = XEL_MAX_FRAME_SIZE;
}
else {
/*
* Use the length in the frame, plus the header and trailer
*/
Length = LengthType + XEL_HEADER_SIZE + XEL_FCS_SIZE;
}
/*
* Read each byte from the EmacLite
*/
XEmacLite_AlignedRead((u32 *) (BaseAddress + XEL_RXBUFF_OFFSET),
FramePtr, Length);
/*
* Acknowledge the frame
*/
Register = XEmacLite_GetRxStatus(BaseAddress);
Register &= ~XEL_RSR_RECV_DONE_MASK;
XEmacLite_SetRxStatus(BaseAddress, Register);
return LengthType;
}
/******************************************************************************/
/**
*
* This function aligns the incoming data and writes it out to a 32-bit
* aligned destination address range.
*
* @param SrcPtr is a pointer to incoming data of any alignment.
* @param DestPtr is a pointer to outgoing data of 32-bit alignment.
* @param ByteCount is the number of bytes to write.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEmacLite_AlignedWrite(void *SrcPtr, u32 *DestPtr, unsigned ByteCount)
{
unsigned Index;
unsigned Length = ByteCount;
volatile u32 AlignBuffer;
volatile u32 *To32Ptr;
u32 *From32Ptr;
volatile u16 *To16Ptr;
u16 *From16Ptr;
volatile u8 *To8Ptr;
u8 *From8Ptr;
To32Ptr = DestPtr;
if ((((u32) SrcPtr) & 0x00000003) == 0) {
/*
* Word aligned buffer, no correction needed.
*/
From32Ptr = (u32 *) SrcPtr;
while (Length > 3) {
/*
* Output each word destination.
*/
*To32Ptr++ = *From32Ptr++;
/*
* Adjust length accordingly
*/
Length -= 4;
}
/*
* Set up to output the remaining data, zero the temp buffer
first.
*/
AlignBuffer = 0;
To8Ptr = (u8 *) &AlignBuffer;
From8Ptr = (u8 *) From32Ptr;
}
else if ((((u32) SrcPtr) & 0x00000001) != 0) {
/*
* Byte aligned buffer, correct.
*/
AlignBuffer = 0;
To8Ptr = (u8 *) &AlignBuffer;
From8Ptr = (u8 *) SrcPtr;
while (Length > 3) {
/*
* Copy each byte into the temporary buffer.
*/
for (Index = 0; Index < 4; Index++) {
*To8Ptr++ = *From8Ptr++;
}
/*
* Output the buffer
*/
*To32Ptr++ = AlignBuffer;
/*.
* Reset the temporary buffer pointer and adjust length.
*/
To8Ptr = (u8 *) &AlignBuffer;
Length -= 4;
}
/*
* Set up to output the remaining data, zero the temp buffer
* first.
*/
AlignBuffer = 0;
To8Ptr = (u8 *) &AlignBuffer;
}
else {
/*
* Half-Word aligned buffer, correct.
*/
AlignBuffer = 0;
/*
* This is a funny looking cast. The new gcc, version 3.3.x has
* a strict cast check for 16 bit pointers, aka short pointers.
* The following warning is issued if the initial 'void *' cast
* is not used:
* 'dereferencing type-punned pointer will break strict-aliasing
* rules'
*/
To16Ptr = (u16 *) ((void *) &AlignBuffer);
From16Ptr = (u16 *) SrcPtr;
while (Length > 3) {
/*
* Copy each half word into the temporary buffer.
*/
for (Index = 0; Index < 2; Index++) {
*To16Ptr++ = *From16Ptr++;
}
/*
* Output the buffer.
*/
*To32Ptr++ = AlignBuffer;
/*
* Reset the temporary buffer pointer and adjust length.
*/
/*
* This is a funny looking cast. The new gcc, version
* 3.3.x has a strict cast check for 16 bit pointers,
* aka short pointers. The following warning is issued
* if the initial 'void *' cast is not used:
* 'dereferencing type-punned pointer will break
* strict-aliasing rules'
*/
To16Ptr = (u16 *) ((void *) &AlignBuffer);
Length -= 4;
}
/*
* Set up to output the remaining data, zero the temp buffer
* first.
*/
AlignBuffer = 0;
To8Ptr = (u8 *) &AlignBuffer;
From8Ptr = (u8 *) From16Ptr;
}
/*
* Output the remaining data, zero the temp buffer first.
*/
for (Index = 0; Index < Length; Index++) {
*To8Ptr++ = *From8Ptr++;
}
*To32Ptr++ = AlignBuffer;
}
/******************************************************************************/
/**
*
* This function reads from a 32-bit aligned source address range and aligns
* the writes to the provided destination pointer alignment.
*
* @param SrcPtr is a pointer to incoming data of 32-bit alignment.
* @param DestPtr is a pointer to outgoing data of any alignment.
* @param ByteCount is the number of bytes to read.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XEmacLite_AlignedRead(u32 *SrcPtr, void *DestPtr, unsigned ByteCount)
{
unsigned Index;
unsigned Length = ByteCount;
volatile u32 AlignBuffer;
u32 *To32Ptr;
volatile u32 *From32Ptr;
u16 *To16Ptr;
volatile u16 *From16Ptr;
u8 *To8Ptr;
volatile u8 *From8Ptr;
From32Ptr = (u32 *) SrcPtr;
if ((((u32) DestPtr) & 0x00000003) == 0) {
/*
* Word aligned buffer, no correction needed.
*/
To32Ptr = (u32 *) DestPtr;
while (Length > 3) {
/*
* Output each word.
*/
*To32Ptr++ = *From32Ptr++;
/*
* Adjust length accordingly.
*/
Length -= 4;
}
/*
* Set up to read the remaining data.
*/
To8Ptr = (u8 *) To32Ptr;
}
else if ((((u32) DestPtr) & 0x00000001) != 0) {
/*
* Byte aligned buffer, correct.
*/
To8Ptr = (u8 *) DestPtr;
while (Length > 3) {
/*
* Copy each word into the temporary buffer.
*/
AlignBuffer = *From32Ptr++;
From8Ptr = (u8 *) &AlignBuffer;
/*
* Write data to destination.
*/
for (Index = 0; Index < 4; Index++) {
*To8Ptr++ = *From8Ptr++;
}
/*
* Adjust length
*/
Length -= 4;
}
}
else {
/*
* Half-Word aligned buffer, correct.
*/
To16Ptr = (u16 *) DestPtr;
while (Length > 3) {
/*
* Copy each word into the temporary buffer.
*/
AlignBuffer = *From32Ptr++;
/*
* This is a funny looking cast. The new gcc, version
* 3.3.x has a strict cast check for 16 bit pointers,
* aka short pointers. The following warning is issued
* if the initial 'void *' cast is not used:
* 'dereferencing type-punned pointer will break
* strict-aliasing rules'
*/
From16Ptr = (u16 *) ((void *) &AlignBuffer);
/*
* Write data to destination.
*/
for (Index = 0; Index < 2; Index++) {
*To16Ptr++ = *From16Ptr++;
}
/*
* Adjust length.
*/
Length -= 4;
}
/*
* Set up to read the remaining data.
*/
To8Ptr = (u8 *) To16Ptr;
}
/*
* Read the remaining data.
*/
AlignBuffer = *From32Ptr++;
From8Ptr = (u8 *) &AlignBuffer;
for (Index = 0; Index < Length; Index++) {
*To8Ptr++ = *From8Ptr++;
}
}
/** @} */

View file

@ -0,0 +1,375 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_l.h
* @addtogroup emaclite_v4_0
* @{
* @details
*
* This header file contains identifiers and basic driver functions and macros
* that can be used to access the Xilinx Ethernet Lite 10/100 MAC (EmacLite).
*
* Refer to xemaclite.h for more details.
*
* @note
*
* The functions and macros in this file assume that the proper device address is
* provided in the argument. If the ping buffer is the source or destination,
* the argument should be DeviceAddress + XEL_(T/R)XBUFF_OFFSET. If the pong
* buffer is the source or destination, the argument should be
* DeviceAddress + XEL_(T/R)XBUFF_OFFSET + XEL_BUFFER_OFFSET. The driver does
* not take the different buffers into consideration.
* For more details on the ping/pong buffer configuration please refer to the
* Ethernet Lite 10/100 Media Access Controller hardware specification.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 06/01/02 First release
* 1.01a ecm 03/31/04 Additional functionality and the _AlignedRead and
* AlignedWrite functions.
* Moved the bulk of description to xemaclite.h
* 1.11a mta 03/21/07 Updated to new coding style
* 2.00a ktn 02/16/09 Added support for MDIO and internal loop back
* 3.00a ktn 10/22/09 The macros have been renamed to remove _m from the name.
* The macros changed in this file are
* XEmacLite_mReadReg changed to XEmacLite_mReadReg,
* XEmacLite_mWriteReg changed to XEmacLite_mWriteReg,
* XEmacLite_mGetTxStatus changed to XEmacLite_GetTxStatus,
* XEmacLite_mSetTxStatus changed to XEmacLite_SetTxStatus,
* XEmacLite_mGetRxStatus changed to XEmacLite_GetRxStatus,
* XEmacLite_mSetRxStatus changed to XEmacLite_SetRxStatus,
* XEmacLite_mIsTxDone changed to XEmacLite_IsTxDone and
* XEmacLite_mIsRxEmpty changed to XEmacLite_IsRxEmpty.
* </pre>
*
******************************************************************************/
#ifndef XEMAC_LITE_L_H /* prevent circular inclusions */
#define XEMAC_LITE_L_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/**
* Register offsets for the Ethernet MAC.
*/
#define XEL_TXBUFF_OFFSET (0x00000000) /**< Transmit Buffer */
#define XEL_MDIOADDR_OFFSET (XEL_TXBUFF_OFFSET + 0x07E4)/**< MDIO Address offset
register */
#define XEL_MDIOWR_OFFSET (XEL_TXBUFF_OFFSET + 0x07E8) /**< MDIO write data
register offset */
#define XEL_MDIORD_OFFSET (XEL_TXBUFF_OFFSET + 0x07EC) /**< MDIO read data
register offset*/
#define XEL_MDIOCNTR_OFFSET (XEL_TXBUFF_OFFSET + 0x07F0)/**< MDIO Control
Register offset */
#define XEL_GIER_OFFSET (XEL_TXBUFF_OFFSET + 0x07F8) /**< Offset for the GIE
Register */
#define XEL_TSR_OFFSET (XEL_TXBUFF_OFFSET + 0x07FC) /**< Tx status */
#define XEL_TPLR_OFFSET (XEL_TXBUFF_OFFSET + 0x07F4) /**< Tx packet length */
#define XEL_RXBUFF_OFFSET (0x00001000) /**< Receive Buffer */
#define XEL_RSR_OFFSET (XEL_RXBUFF_OFFSET + 0x07FC) /**< Rx status */
#define XEL_RPLR_OFFSET (XEL_RXBUFF_OFFSET + 0x0C) /**< Rx packet length */
#define XEL_MAC_HI_OFFSET (XEL_TXBUFF_OFFSET + 0x14) /**< MAC address hi
offset */
#define XEL_MAC_LO_OFFSET (XEL_TXBUFF_OFFSET) /**< MAC address lo
offset */
#define XEL_BUFFER_OFFSET (0x00000800) /**< Next buffer's
offset same for
both TX and RX */
/**
* MDIO Address/Write Data/Read Data Register Bit Masks
*/
#define XEL_MDIO_ADDRESS_MASK 0x00003E0 /**< PHY Address mask */
#define XEL_MDIO_ADDRESS_SHIFT 0x5 /**< PHY Address shift*/
#define XEL_MDIO_OP_MASK 0x00000400 /**< PHY read access */
/**
* MDIO Control Register Bit Masks
*/
#define XEL_MDIOCNTR_STATUS_MASK 0x00000001 /**< MDIO transfer in
Progress */
#define XEL_MDIOCNTR_ENABLE_MASK 0x00000008 /**< MDIO Enable */
/**
* Global Interrupt Enable Register (GIER) Bit Masks
*/
#define XEL_GIER_GIE_MASK 0x80000000 /**< Global Enable */
/**
* Transmit Status Register (TSR) Bit Masks
*/
#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /**< Xmit complete */
#define XEL_TSR_PROGRAM_MASK 0x00000002 /**< Program the MAC
address */
#define XEL_TSR_XMIT_IE_MASK 0x00000008 /**< Xmit interrupt
enable bit */
#define XEL_TSR_LOOPBACK_MASK 0x00000010 /**< Loop back enable
bit */
#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /**< Buffer is active,
SW bit only. This
is not documented
in the HW spec */
/**
* define for programming the MAC address into the EmacLite
*/
#define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
/**
* Receive Status Register (RSR)
*/
#define XEL_RSR_RECV_DONE_MASK 0x00000001 /**< Recv complete */
#define XEL_RSR_RECV_IE_MASK 0x00000008 /**< Recv interrupt
enable bit */
/**
* Transmit Packet Length Register (TPLR)
*/
#define XEL_TPLR_LENGTH_MASK_HI 0x0000FF00 /**< Transmit packet length
upper byte */
#define XEL_TPLR_LENGTH_MASK_LO 0x000000FF /**< Transmit packet length
lower byte */
/**
* Receive Packet Length Register (RPLR)
*/
#define XEL_RPLR_LENGTH_MASK_HI 0x0000FF00 /**< Receive packet length
upper byte */
#define XEL_RPLR_LENGTH_MASK_LO 0x000000FF /**< Receive packet length
lower byte */
#define XEL_HEADER_SIZE 14 /**< Size of header in bytes */
#define XEL_MTU_SIZE 1500 /**< Max size of data in frame */
#define XEL_FCS_SIZE 4 /**< Size of CRC */
#define XEL_HEADER_OFFSET 12 /**< Offset to length field */
#define XEL_HEADER_SHIFT 16 /**< Right shift value to align
length */
#define XEL_MAX_FRAME_SIZE (XEL_HEADER_SIZE+XEL_MTU_SIZE+ XEL_FCS_SIZE) /**< Max
length of Rx frame used if
length/type field
contains the type (> 1500) */
#define XEL_MAX_TX_FRAME_SIZE (XEL_HEADER_SIZE + XEL_MTU_SIZE) /**< Max
length of Tx frame */
#define XEL_MAC_ADDR_SIZE 6 /**< length of MAC address */
/*
* General Ethernet Definitions
*/
#define XEL_ETHER_PROTO_TYPE_IP 0x0800 /**< IP Protocol */
#define XEL_ETHER_PROTO_TYPE_ARP 0x0806 /**< ARP Protocol */
#define XEL_ETHER_PROTO_TYPE_VLAN 0x8100 /**< VLAN Tagged */
#define XEL_ARP_PACKET_SIZE 28 /**< Max ARP packet size */
#define XEL_HEADER_IP_LENGTH_OFFSET 16 /**< IP Length Offset */
#define XEL_VLAN_TAG_SIZE 4 /**< VLAN Tag Size */
/***************** Macros (Inline Functions) Definitions *********************/
#define XEmacLite_In32 Xil_In32
#define XEmacLite_Out32 Xil_Out32
/****************************************************************************/
/**
*
* Read from the specified EmacLite device register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to select the specific register.
*
* @return The value read from the register.
*
* @note C-Style signature:
* u32 XEmacLite_ReadReg(u32 BaseAddress, u32 RegOffset);
*
******************************************************************************/
#define XEmacLite_ReadReg(BaseAddress, RegOffset) \
XEmacLite_In32((BaseAddress) + (RegOffset))
/***************************************************************************/
/**
*
* Write to the specified EmacLite device register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to select the specific register.
* @param RegisterValue is the value to be written to the register.
*
* @return None.
*
* @note C-Style signature:
* void XEmacLite_WriteReg(u32 BaseAddress, u32 RegOffset,
* u32 RegisterValue);
******************************************************************************/
#define XEmacLite_WriteReg(BaseAddress, RegOffset, RegisterValue) \
XEmacLite_Out32((BaseAddress) + (RegOffset), (RegisterValue))
/****************************************************************************/
/**
*
* Get the Tx Status Register Contents.
*
* @param BaseAddress is the base address of the device
*
* @return The contents of the Tx Status Register.
*
* @note C-Style signature:
* u32 XEmacLite_GetTxStatus(u32 BaseAddress)
*
*****************************************************************************/
#define XEmacLite_GetTxStatus(BaseAddress) \
(XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET))
/****************************************************************************/
/**
*
* Set the Tx Status Register Contents.
*
* @param BaseAddress is the base address of the device
* @param Data is the value to be written to the Register.
*
* @return None.
*
* @note C-Style signature:
* u32 XEmacLite_SetTxStatus(u32 BaseAddress, u32 Data)
*
*****************************************************************************/
#define XEmacLite_SetTxStatus(BaseAddress, Data) \
(XEmacLite_WriteReg((BaseAddress), XEL_TSR_OFFSET, (Data)))
/****************************************************************************/
/**
*
* Get the Rx Status Register Contents.
*
* @param BaseAddress is the base address of the device
*
* @return The contents of the Rx Status Register.
*
* @note C-Style signature:
* u32 XEmacLite_GetRxStatus(u32 BaseAddress)
*
*****************************************************************************/
#define XEmacLite_GetRxStatus(BaseAddress) \
(XEmacLite_ReadReg((BaseAddress), XEL_RSR_OFFSET))
/****************************************************************************/
/**
*
* Set the Rx Status Register Contents.
*
* @param BaseAddress is the base address of the device
* @param Data is the value to be written to the Register.
*
* @return None.
*
* @note C-Style signature:
* u32 XEmacLite_SetRxStatus(u32 BaseAddress, u32 Data)
*
*****************************************************************************/
#define XEmacLite_SetRxStatus(BaseAddress, Data) \
(XEmacLite_WriteReg((BaseAddress), XEL_RSR_OFFSET, (Data)))
/****************************************************************************/
/**
*
* Check to see if the transmission is complete.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if it is done, or FALSE if it is not.
*
* @note C-Style signature:
* int XEmacLite_IsTxDone(u32 BaseAddress)
*
*****************************************************************************/
#define XEmacLite_IsTxDone(BaseAddress) \
((XEmacLite_ReadReg((BaseAddress), XEL_TSR_OFFSET) & \
XEL_TSR_XMIT_BUSY_MASK) != XEL_TSR_XMIT_BUSY_MASK)
/****************************************************************************/
/**
*
* Check to see if the receive is empty.
*
* @param BaseAddress is the base address of the device
*
* @return TRUE if it is empty, or FALSE if it is not.
*
* @note C-Style signature:
* int XEmacLite_IsRxEmpty(u32 BaseAddress)
*
*****************************************************************************/
#define XEmacLite_IsRxEmpty(BaseAddress) \
((XEmacLite_ReadReg((BaseAddress), XEL_RSR_OFFSET) & \
XEL_RSR_RECV_DONE_MASK) != XEL_RSR_RECV_DONE_MASK)
/************************** Function Prototypes ******************************/
void XEmacLite_SendFrame(u32 BaseAddress, u8 *FramePtr, unsigned ByteCount);
u16 XEmacLite_RecvFrame(u32 BaseAddress, u8 *FramePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,212 @@
/******************************************************************************
*
* Copyright (C) 2004 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_selftest.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* Function(s) in this file are the required functions for the EMAC Lite
* driver sefftest for the hardware.
* See xemaclite.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.01a ecm 01/31/04 First release
* 1.11a mta 03/21/07 Updated to new coding style
* 3.00a ktn 10/22/09 Updated driver to use the HAL Processor APIs/macros.
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_io.h"
#include "xemaclite.h"
#include "xemaclite_i.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Performs a SelfTest on the EmacLite device as follows:
* - Writes to the mandatory TX buffer and reads back to verify.
* - If configured, writes to the secondary TX buffer and reads back to verify.
* - Writes to the mandatory RX buffer and reads back to verify.
* - If configured, writes to the secondary RX buffer and reads back to verify.
*
*
* @param InstancePtr is a pointer to the XEmacLite instance .
*
* @return
* - XST_SUCCESS if the device Passed the Self Test.
* - XST_FAILURE if any of the data read backs fail.
*
* @note None.
*
******************************************************************************/
int XEmacLite_SelfTest(XEmacLite * InstancePtr)
{
u32 BaseAddress;
u8 Index;
u8 TestString[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
u8 ReturnString[4] = { 0x0, 0x0, 0x0, 0x0 };
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Determine the TX buffer address
*/
BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress +
XEL_TXBUFF_OFFSET;
/*
* Write the TestString to the TX buffer in EMAC Lite then
* back from the EMAC Lite and verify
*/
XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress,
sizeof(TestString));
XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString,
sizeof(ReturnString));
for (Index = 0; Index < 4; Index++) {
if (ReturnString[Index] != TestString[Index]) {
return XST_FAILURE;
}
/*
* Zero the return string for the next test
*/
ReturnString[Index] = 0;
}
/*
* If the second buffer is configured, test it also
*/
if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
BaseAddress += XEL_BUFFER_OFFSET;
/*
* Write the TestString to the optional TX buffer in EMAC Lite
* then back from the EMAC Lite and verify
*/
XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress,
sizeof(TestString));
XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString,
sizeof(ReturnString));
for (Index = 0; Index < 4; Index++) {
if (ReturnString[Index] != TestString[Index]) {
return XST_FAILURE;
}
/*
* Zero the return string for the next test
*/
ReturnString[Index] = 0;
}
}
/*
* Determine the RX buffer address
*/
BaseAddress = InstancePtr->EmacLiteConfig.BaseAddress +
XEL_RXBUFF_OFFSET;
/*
* Write the TestString to the RX buffer in EMAC Lite then
* back from the EMAC Lite and verify
*/
XEmacLite_AlignedWrite(TestString, (u32 *) (BaseAddress),
sizeof(TestString));
XEmacLite_AlignedRead((u32 *) (BaseAddress), ReturnString,
sizeof(ReturnString));
for (Index = 0; Index < 4; Index++) {
if (ReturnString[Index] != TestString[Index]) {
return XST_FAILURE;
}
/*
* Zero the return string for the next test
*/
ReturnString[Index] = 0;
}
/*
* If the second buffer is configured, test it also
*/
if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
BaseAddress += XEL_BUFFER_OFFSET;
/*
* Write the TestString to the optional RX buffer in EMAC Lite
* then back from the EMAC Lite and verify
*/
XEmacLite_AlignedWrite(TestString, (u32 *) BaseAddress,
sizeof(TestString));
XEmacLite_AlignedRead((u32 *) BaseAddress, ReturnString,
sizeof(ReturnString));
for (Index = 0; Index < 4; Index++) {
if (ReturnString[Index] != TestString[Index]) {
return XST_FAILURE;
}
/*
* Zero the return string for the next test
*/
ReturnString[Index] = 0;
}
}
return XST_SUCCESS;
}
/** @} */

View file

@ -0,0 +1,157 @@
/******************************************************************************
*
* Copyright (C) 2007 - 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
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemaclite_sinit.c
* @addtogroup emaclite_v4_0
* @{
* @details
*
* This file contains the implementation of the XEmacLite driver's static
* initialization functionality.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.12a sv 11/28/07 First release
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xemaclite.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XEmacLite_Config XEmacLite_ConfigTable[];
/*****************************************************************************/
/**
*
* Lookup the device configuration based on the unique device ID. The table
* XEmacLite_ConfigTable contains the configuration info for each device in the
* system.
*
* @param DeviceId is the unique device ID of the device being looked up.
*
* @return A pointer to the configuration table entry corresponding to the
* given device ID, or NULL if no match is found.
*
* @note None.
*
******************************************************************************/
XEmacLite_Config *XEmacLite_LookupConfig(u16 DeviceId)
{
XEmacLite_Config *CfgPtr = NULL;
u32 Index;
for (Index = 0; Index < XPAR_XEMACLITE_NUM_INSTANCES; Index++) {
if (XEmacLite_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XEmacLite_ConfigTable[Index];
break;
}
}
return CfgPtr;
}
/*****************************************************************************/
/**
*
* Initialize a specific XEmacLite instance/driver. The initialization entails:
* - Initialize fields of the XEmacLite instance structure.
*
* The driver defaults to polled mode operation.
*
* @param InstancePtr is a pointer to the XEmacLite instance.
* @param DeviceId is the unique id of the device controlled by this
* XEmacLite instance. Passing in a device id associates the
* generic XEmacLite instance to a specific device, as chosen by
* the caller or application developer.
*
* @return
* - XST_SUCCESS if initialization was successful.
* - XST_DEVICE_NOT_FOUND/XST_FAILURE if device configuration
* information was not found for a device with the supplied
* device ID.
*
* @note None
*
******************************************************************************/
int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId)
{
int Status;
XEmacLite_Config *EmacLiteConfigPtr;/* Pointer to Configuration data. */
/*
* Verify that each of the inputs are valid.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
/*
* Lookup the device configuration in the configuration table. Use this
* configuration info down below when initializing this driver.
*/
EmacLiteConfigPtr = XEmacLite_LookupConfig(DeviceId);
if (EmacLiteConfigPtr == NULL) {
return XST_DEVICE_NOT_FOUND;
}
Status = XEmacLite_CfgInitialize(InstancePtr,
EmacLiteConfigPtr,
EmacLiteConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/** @} */