
Added initial support Xilinx Embedded Software. Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
1391 lines
37 KiB
C
Executable file
1391 lines
37 KiB
C
Executable file
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* Use of the Software is limited solely to applications:
|
|
* (a) running on a Xilinx device, or
|
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
|
* this Software without prior written authorization from Xilinx.
|
|
*
|
|
******************************************************************************/
|
|
/**
|
|
*
|
|
* @file xaxiethernet_example_intr_fifo.c
|
|
*
|
|
* Implements examples that utilize the Axi Ethernet's interrupt driven FIFO
|
|
* direct packet transfer mode to send and receive frames.
|
|
*
|
|
* These examples demonstrate:
|
|
*
|
|
* - How to perform simple send and receive.
|
|
* - Advanced frame processing
|
|
* - Error handling
|
|
* - Device reset
|
|
*
|
|
* Functional guide to example:
|
|
*
|
|
* - AxiEthernetSingleFrameIntrExample() demonstrates the simplest way to send
|
|
* and receive frames in interrupt driven FIFO direct mode.
|
|
*
|
|
* - AxiEthernetSingleFrameNonContIntrExample demonstrates how to handle frames
|
|
* that are stored in more than one memory location.
|
|
*
|
|
* - AxiEthernetMultipleFramesIntrExample demonstrates how to defer frame
|
|
* reception so that CPU intensive receive functions are not performed in
|
|
* interrupt context.
|
|
*
|
|
* - AxiEthernetErrorHandler() demonstrates how to manage asynchronous errors.
|
|
*
|
|
* - AxiEthernetResetDevice() demonstrates how to reset the driver/HW while
|
|
maintaining driver/HW state.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ----- ---- -------- -------------------------------------------------------
|
|
* 1.00a asa 4/30/10 First release based on the ll temac driver
|
|
* 3.00a bss 10/22/12 Added support for Fast Interrupt Handlers.
|
|
* 3.01a srt 02/14/13 Added support for Zynq (CR 681136)
|
|
* 3.02a srt 08/06/13 Fixed CR 727634 -
|
|
* Modified FifoHandler() logic to reflect the bit
|
|
* changes in the Interrupt Status Register as per
|
|
* the latest AXI FIFO stream IP.
|
|
*
|
|
* </pre>
|
|
*
|
|
******************************************************************************/
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include "xaxiethernet_example.h"
|
|
#include "xllfifo.h"
|
|
#include "xil_cache.h"
|
|
#include "xil_exception.h"
|
|
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
#include "xintc.h"
|
|
#else
|
|
#include "xscugic.h"
|
|
#endif
|
|
|
|
#ifdef XPAR_XUARTNS550_NUM_INSTANCES
|
|
#include "xuartns550_l.h"
|
|
#endif
|
|
/*************************** 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.
|
|
*/
|
|
#ifndef TESTAPP_GEN
|
|
#define AXIETHERNET_DEVICE_ID XPAR_AXIETHERNET_0_DEVICE_ID
|
|
#define FIFO_DEVICE_ID XPAR_AXI_FIFO_0_DEVICE_ID
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
|
|
#define AXIETHERNET_IRPT_INTR XPAR_INTC_0_AXIETHERNET_0_VEC_ID
|
|
#define FIFO_IRPT_INTR XPAR_INTC_0_LLFIFO_0_VEC_ID
|
|
#else
|
|
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
|
#define AXIETHERNET_IRPT_INTR XPAR_FABRIC_AXIETHERNET_0_VEC_ID
|
|
#define FIFO_IRPT_INTR XPAR_FABRIC_LLFIFO_0_VEC_ID
|
|
#endif
|
|
#endif
|
|
|
|
#define PAYLOAD_SIZE 100 /* Payload size used in examples */
|
|
/*************************** Variable Definitions ****************************/
|
|
|
|
static EthernetFrame TxFrame; /* Frame used to send with */
|
|
static EthernetFrame RxFrame; /* Frame used to receive data */
|
|
volatile static int DeferRx = 0;
|
|
|
|
/*
|
|
* Counters setup to be incremented by callbacks
|
|
*/
|
|
static volatile int FramesRx; /* Number of received frames */
|
|
static volatile int FramesRxInts; /* Number of ints for received
|
|
* frames
|
|
*/
|
|
static volatile int FramesTxInts; /* Number of ints for sent frames */
|
|
static volatile int DeviceErrors; /* Num of errors detected in
|
|
* the device
|
|
*/
|
|
static volatile int FrameDataErrors; /* Num of times frame data check
|
|
* failed
|
|
*/
|
|
XAxiEthernet AxiEthernetInstance;
|
|
XLlFifo FifoInstance;
|
|
|
|
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
#define INTC XIntc
|
|
#define INTC_HANDLER XIntc_InterruptHandler
|
|
#else
|
|
#define INTC XScuGic
|
|
#define INTC_HANDLER XScuGic_InterruptHandler
|
|
#endif
|
|
|
|
#ifndef TESTAPP_GEN
|
|
static INTC IntcInstance;
|
|
#endif
|
|
|
|
#if XPAR_INTC_0_HAS_FAST == 1
|
|
|
|
/* Variables for Fast Interrupt Handlers */
|
|
XAxiEthernet *AxiEthernetInstancePtr_Fast;
|
|
XLlFifo *Fifo_Fast;
|
|
|
|
/****** Fast Interrupt Handlers prototypes ******/
|
|
|
|
static void AxiEthernetErrorFastHandler(void) __attribute__ ((fast_interrupt));
|
|
|
|
static void FifoFastHandler(void) __attribute__ ((fast_interrupt));
|
|
|
|
#else
|
|
|
|
static void AxiEthernetErrorHandler(XAxiEthernet *AxiEthernet);
|
|
static void FifoHandler(XLlFifo *Fifo);
|
|
|
|
#endif
|
|
|
|
|
|
/*************************** Function Prototypes *****************************/
|
|
|
|
/*
|
|
* The different examples given in this file
|
|
*/
|
|
int AxiEthernetFifoIntrExample(INTC *IntcInstancePtr,
|
|
XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr,
|
|
u16 AxiEthernetDeviceId,
|
|
u16 FifoDeviceId, u16 AxiEthernetIntrId,
|
|
u16 FifoIntrId);
|
|
int AxiEthernetSingleFrameIntrExample(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr);
|
|
int AxiEthernetSingleFrameNonContIntrExample(XAxiEthernet
|
|
*AxiEthernetInstancePtr, XLlFifo *FifoInstancePtr);
|
|
int AxiEthernetMultipleFramesIntrExample(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr);
|
|
|
|
|
|
/*
|
|
* The Interrupt setup and callbacks
|
|
*/
|
|
static int AxiEthernetSetupIntrSystem(INTC *IntcInstancePtr,
|
|
XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr,
|
|
u16 AxiEthernetIntrId, u16 FifoIntrId);
|
|
static void AxiEthernetDisableIntrSystem(INTC *IntcInstancePtr,
|
|
u16 AxiEthernetIntrId, u16 FifoIntrId);
|
|
|
|
static void FifoRecvHandler(XLlFifo *Fifo);
|
|
|
|
/*
|
|
* Utility routines
|
|
*/
|
|
static int AxiEthernetResetDevice(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr);
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the main function for the Axi Ethernet example. This function is not
|
|
* included if the example is generated from the TestAppGen test tool.
|
|
*
|
|
* @param None.
|
|
*
|
|
* - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
* @note None.
|
|
*
|
|
****************************************************************************/
|
|
#ifndef TESTAPP_GEN
|
|
int main(void)
|
|
{
|
|
int Status;
|
|
|
|
#ifdef XPAR_XUARTNS550_NUM_INSTANCES
|
|
XUartNs550_SetBaud(STDIN_BASEADDRESS, XPAR_XUARTNS550_CLOCK_HZ, 9600);
|
|
XUartNs550_SetLineControlReg(STDIN_BASEADDRESS, XUN_LCR_8_DATA_BITS);
|
|
#endif
|
|
#if XPAR_MICROBLAZE_USE_ICACHE
|
|
Xil_ICacheInvalidate();
|
|
Xil_ICacheEnable();
|
|
#endif
|
|
|
|
#if XPAR_MICROBLAZE_USE_DCACHE
|
|
Xil_DCacheInvalidate();
|
|
Xil_DCacheEnable();
|
|
#endif
|
|
|
|
AxiEthernetUtilErrorTrap("\r\n--- Enter main() ---");
|
|
AxiEthernetUtilErrorTrap("This test may take several minutes to finish");
|
|
|
|
|
|
/*
|
|
* Call the Axi Ethernet interrupt example , specify the parameters
|
|
* generated in xparameters.h
|
|
*/
|
|
Status = AxiEthernetFifoIntrExample(&IntcInstance,
|
|
&AxiEthernetInstance,
|
|
&FifoInstance,
|
|
AXIETHERNET_DEVICE_ID,
|
|
FIFO_DEVICE_ID,
|
|
AXIETHERNET_IRPT_INTR, FIFO_IRPT_INTR);
|
|
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Failed test intr fifo");
|
|
} else {
|
|
AxiEthernetUtilErrorTrap("Test passed");
|
|
}
|
|
|
|
AxiEthernetUtilErrorTrap("--- Exiting main() ---");
|
|
|
|
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function demonstrates the usage usage of the Axi Ethernet by sending
|
|
* and receiving frames in interrupt driven fifo mode.
|
|
*
|
|
*
|
|
* @param IntcInstancePtr is a pointer to the instance of the Intc
|
|
* component.
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* Axi Ethernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the AXIFIFO
|
|
* component.
|
|
* @param AxiEthernetDeviceId is Device ID of the Axi Ethernet Device ,
|
|
* typically XPAR_<AXIETHERNET_instance>_DEVICE_ID value from
|
|
* xparameters.h.
|
|
* @param FifoDeviceId is the Interrupt ID and is typically
|
|
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
|
|
* value from xparameters.h.
|
|
* @param AxiEthernetIntrId is the Interrupt ID and is typically
|
|
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
|
|
* value from xparameters.h.
|
|
* @param FifoIntrId is the interrupt id for fifo.
|
|
*
|
|
* - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note AxiFifo hardware must be initialized before initializing
|
|
* AxiEthernet. Since AxiFifo reset line is connected to the
|
|
* AxiEthernet reset line, a reset of AxiFifo hardware during its
|
|
* initialization would reset AxiEthernet.
|
|
*
|
|
******************************************************************************/
|
|
int AxiEthernetFifoIntrExample(INTC *IntcInstancePtr,
|
|
XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr,
|
|
u16 AxiEthernetDeviceId,
|
|
u16 FifoDeviceId, u16 AxiEthernetIntrId,
|
|
u16 FifoIntrId)
|
|
{
|
|
int Status;
|
|
XAxiEthernet_Config *MacCfgPtr;
|
|
int LoopbackSpeed;
|
|
|
|
|
|
/*************************************/
|
|
/* Setup device for first-time usage */
|
|
/*************************************/
|
|
|
|
/*
|
|
* Get the configuration of AxiEthernet hardware.
|
|
*/
|
|
MacCfgPtr = XAxiEthernet_LookupConfig(AxiEthernetDeviceId);
|
|
|
|
/*
|
|
* Check whether AXIFIFO is present or not
|
|
*/
|
|
if(MacCfgPtr->AxiDevType != XPAR_AXI_FIFO) {
|
|
AxiEthernetUtilErrorTrap
|
|
("Device HW not configured for FIFO mode\r\n");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Initialize AXIFIFO hardware. AXIFIFO must be initialized before
|
|
* AxiEthernet. During AXIFIFO initialization, AXIFIFO hardware is
|
|
* reset, and since AXIFIFO reset line is connected to AxiEthernet,
|
|
* this would ensure a reset of AxiEthernet.
|
|
*/
|
|
XLlFifo_Initialize(FifoInstancePtr, MacCfgPtr->AxiDevBaseAddress);
|
|
|
|
/*
|
|
* Initialize AxiEthernet hardware.
|
|
*/
|
|
Status = XAxiEthernet_CfgInitialize(AxiEthernetInstancePtr, MacCfgPtr,
|
|
MacCfgPtr->BaseAddress);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Error in initialize");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Set the MAC address
|
|
*/
|
|
Status = XAxiEthernet_SetMacAddress(AxiEthernetInstancePtr,
|
|
(u8 *) AxiEthernetMAC);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Error setting MAC address");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Set PHY to loopback, speed depends on phy type.
|
|
* MII is 100 and all others are 1000.
|
|
*/
|
|
if (XAxiEthernet_GetPhysicalInterface(AxiEthernetInstancePtr) ==
|
|
XAE_PHY_TYPE_MII) {
|
|
LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED;
|
|
} else {
|
|
LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED_1G;
|
|
}
|
|
Status = AxiEthernetUtilEnterLoopback(AxiEthernetInstancePtr,
|
|
LoopbackSpeed);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Error setting the PHY loopback");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Set PHY<-->MAC data clock
|
|
*/
|
|
Status = XAxiEthernet_SetOperatingSpeed(AxiEthernetInstancePtr,
|
|
(u16)LoopbackSpeed);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Setting the operating speed of the MAC needs a delay. There
|
|
* doesn't seem to be register to poll, so please consider this
|
|
* during your application design.
|
|
*/
|
|
AxiEthernetUtilPhyDelay(2);
|
|
|
|
/* Clear any pending FIFO interrupts from any previous
|
|
* examples (e.g., polled)
|
|
*/
|
|
XLlFifo_IntClear(FifoInstancePtr, XLLF_INT_ALL_MASK);
|
|
|
|
/*
|
|
* Connect to the interrupt controller and enable interrupts
|
|
*/
|
|
Status = AxiEthernetSetupIntrSystem(IntcInstancePtr,
|
|
AxiEthernetInstancePtr,
|
|
FifoInstancePtr, AxiEthernetIntrId,
|
|
FifoIntrId);
|
|
|
|
/****************************/
|
|
/* Run through the examples */
|
|
/****************************/
|
|
|
|
|
|
/*
|
|
* Run the AxiEthernet Single Frame Interrupt example
|
|
*/
|
|
Status = AxiEthernetSingleFrameIntrExample(AxiEthernetInstancePtr,
|
|
FifoInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Run the AxiEthernet Single Frame Non Continuous Interrupt example
|
|
*/
|
|
Status = AxiEthernetSingleFrameNonContIntrExample
|
|
(AxiEthernetInstancePtr, FifoInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
DeferRx = 1;
|
|
Status = AxiEthernetMultipleFramesIntrExample(AxiEthernetInstancePtr,
|
|
FifoInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
Status = AxiEthernetResetDevice(AxiEthernetInstancePtr,
|
|
FifoInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Disable the interrupts for the AxiEthernet device
|
|
*/
|
|
AxiEthernetDisableIntrSystem(IntcInstancePtr, AxiEthernetIntrId,
|
|
FifoIntrId);
|
|
|
|
|
|
/*
|
|
* Stop the device
|
|
*/
|
|
XAxiEthernet_Stop(AxiEthernetInstancePtr);
|
|
|
|
|
|
return XST_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function demonstrates the usage of the Axi Ethernet by sending and
|
|
* receiving a single frame in interrupt mode.
|
|
*
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* AxiEthernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the Fifo
|
|
* component.
|
|
*
|
|
* - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int AxiEthernetSingleFrameIntrExample(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr)
|
|
{
|
|
u32 FifoFreeBytes;
|
|
u32 TxFrameLength;
|
|
int PayloadSize = PAYLOAD_SIZE;
|
|
|
|
/*
|
|
* Clear variables shared with callbacks
|
|
*/
|
|
FramesRx = 0;
|
|
FramesRxInts = 0;
|
|
FramesTxInts = 0;
|
|
DeviceErrors = 0;
|
|
FrameDataErrors = 0;
|
|
|
|
/*
|
|
* Setup packet to be transmitted
|
|
*/
|
|
AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
|
|
AxiEthernetUtilFrameHdrFormatType(&TxFrame, PayloadSize);
|
|
AxiEthernetUtilFrameSetPayloadData(&TxFrame, PayloadSize);
|
|
|
|
/*
|
|
* Clear out receive packet memory area
|
|
*/
|
|
AxiEthernetUtilFrameMemClear(&RxFrame);
|
|
|
|
/*
|
|
* Calculate frame length (not including FCS)
|
|
*/
|
|
TxFrameLength = XAE_HDR_SIZE + PayloadSize;
|
|
|
|
/****************/
|
|
/* Setup device */
|
|
/****************/
|
|
|
|
/*
|
|
* Start the device
|
|
*/
|
|
XAxiEthernet_Start(AxiEthernetInstancePtr);
|
|
|
|
/*
|
|
* Enable the interrupts
|
|
*/
|
|
XLlFifo_IntEnable(FifoInstancePtr, XLLF_INT_ALL_MASK);
|
|
XAxiEthernet_IntEnable(AxiEthernetInstancePtr,
|
|
XAE_INT_RXRJECT_MASK | XAE_INT_RXFIFOOVR_MASK);
|
|
|
|
|
|
/*******************/
|
|
/* Send the packet */
|
|
/*******************/
|
|
|
|
/*
|
|
* Find out how much room is in the FIFO
|
|
* Vacancy is a value in 32 bit words. Multiply by 4 to get bytes.
|
|
*/
|
|
FifoFreeBytes = XLlFifo_TxVacancy(FifoInstancePtr) * 4;
|
|
if (FifoFreeBytes < TxFrameLength) {
|
|
AxiEthernetUtilErrorTrap("Not enough room in FIFO for frame");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Write frame data to FIFO
|
|
*/
|
|
XLlFifo_Write(FifoInstancePtr, TxFrame, TxFrameLength);
|
|
|
|
/*
|
|
* Initiate the transmit
|
|
*/
|
|
XLlFifo_TxSetLen(FifoInstancePtr, TxFrameLength);
|
|
|
|
/*
|
|
* Wait for receive indication or error
|
|
*/
|
|
while ((FramesRx == 0) && (DeviceErrors == 0));
|
|
|
|
/*
|
|
* Stop the device
|
|
*/
|
|
XAxiEthernet_Stop(AxiEthernetInstancePtr);
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This example sends a packet from non-contiguous memory locations. The header
|
|
* is stored in one area. The payload data is calculated and written to the
|
|
* packet FIFO one byte at a time.
|
|
*
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* AxiEthernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the Fifo
|
|
* component.
|
|
*
|
|
* - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int AxiEthernetSingleFrameNonContIntrExample(XAxiEthernet
|
|
*AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr)
|
|
{
|
|
u32 FifoFreeBytes;
|
|
int PayloadSize = 20;
|
|
u8 PayloadData;
|
|
u32 TxFrameLength;
|
|
|
|
/*
|
|
* Clear variables shared with callbacks
|
|
*/
|
|
FramesRx = 0;
|
|
FramesRxInts = 0;
|
|
FramesTxInts = 0;
|
|
DeviceErrors = 0;
|
|
FrameDataErrors = 0;
|
|
|
|
/*
|
|
* Setup the transmit packet header
|
|
*/
|
|
AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
|
|
AxiEthernetUtilFrameHdrFormatType(&TxFrame, PayloadSize);
|
|
|
|
/*
|
|
* Clear out receive packet memory area
|
|
*/
|
|
AxiEthernetUtilFrameMemClear(&RxFrame);
|
|
|
|
/*
|
|
* Calculate frame length (not including FCS)
|
|
*/
|
|
TxFrameLength = XAE_HDR_SIZE + PayloadSize;
|
|
|
|
/****************/
|
|
/* Setup device */
|
|
/****************/
|
|
|
|
/*
|
|
* Start the device
|
|
*/
|
|
XAxiEthernet_Start(AxiEthernetInstancePtr);
|
|
|
|
/*
|
|
* Enable interrupts
|
|
*/
|
|
XLlFifo_IntEnable(FifoInstancePtr, XLLF_INT_ALL_MASK);
|
|
|
|
/*******************/
|
|
/* Send the packet */
|
|
/*******************/
|
|
|
|
/*
|
|
* Make sure there is enough room for a full sized frame
|
|
* Vacancy is a value in 32 bit words. Multiply by 4 to get bytes.
|
|
*/
|
|
FifoFreeBytes = XLlFifo_TxVacancy(FifoInstancePtr) * 4;
|
|
|
|
if (FifoFreeBytes < (XAE_MTU + XAE_HDR_SIZE)) {
|
|
AxiEthernetUtilErrorTrap("Not enough room in FIFO for frame");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Write the header data
|
|
*/
|
|
XLlFifo_Write(FifoInstancePtr, TxFrame, XAE_HDR_SIZE);
|
|
|
|
/*
|
|
* Write payload one byte at a time. Set the payload like the
|
|
* AxiEthernetUtilFrameSetPayloadData() function would. This is done
|
|
* so that the received packet will pass validation in
|
|
* AxiEthernetRecvHandler().
|
|
*
|
|
* Keep PayloadSize less than 255 since
|
|
* AxiEthernetUtilFrameSetPayloadData() switches to a 16 bit
|
|
* counter at 256.
|
|
*
|
|
* This is not the fastest way to send a frame of data but it does
|
|
* illustrate the flexibility of the API.
|
|
*/
|
|
PayloadData = 0;
|
|
while ((PayloadData < PayloadSize) && (DeviceErrors == 0)) {
|
|
XLlFifo_Write(FifoInstancePtr, &PayloadData, 1);
|
|
PayloadData++;
|
|
}
|
|
|
|
/*
|
|
* Did it all get written without error
|
|
*/
|
|
if (DeviceErrors != 0) {
|
|
AxiEthernetUtilErrorTrap
|
|
("Error writing payload to FIFO, reset recommended");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Now begin transmission
|
|
*/
|
|
XLlFifo_TxSetLen(FifoInstancePtr, TxFrameLength);
|
|
|
|
/*
|
|
* Wait for receive indication or error
|
|
*/
|
|
while ((FramesRx == 0) && (DeviceErrors == 0));
|
|
|
|
/*
|
|
* Stop the device
|
|
*/
|
|
XAxiEthernet_Stop(AxiEthernetInstancePtr);
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This example sends and receives a batch of frames. Frame reception is handled
|
|
* in this function and not in the callback function.
|
|
*
|
|
* Use this method of reception when interrupt latency is important.
|
|
*
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* AxiEthernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the Fifo
|
|
* component.
|
|
*
|
|
* - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int AxiEthernetMultipleFramesIntrExample(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr)
|
|
{
|
|
int FramesToLoopback;
|
|
int PayloadSize;
|
|
u32 TxFrameLength;
|
|
u32 RxFrameLength;
|
|
int Index;
|
|
|
|
/*
|
|
* Clear variables shared with callbacks
|
|
*/
|
|
FramesRx = 0;
|
|
FramesRxInts = 0;
|
|
FramesTxInts = 0;
|
|
DeviceErrors = 0;
|
|
FrameDataErrors = 0;
|
|
|
|
/*
|
|
* Setup the number of frames to loopback and the size of the frame to
|
|
* loopback. The default settings should work for every case. Modifying
|
|
* the settings can cause problems, see discussion below:
|
|
*
|
|
* If PayloadSize is set small and FramesToLoopback high, then it is
|
|
* possible to cause the transmit status FIFO to overflow.
|
|
*
|
|
* If PayloadSize is set large and FramesToLoopback high, then it is
|
|
* possible to cause the transmit packet FIFO to overflow.
|
|
*
|
|
* Either of these scenarios may be worth trying out to observe how the
|
|
* driver reacts. The exact values to cause these types of errors
|
|
* will vary due to the sizes of the FIFOs selected at hardware build
|
|
* time. But the following settings should create problems for all
|
|
* FIFO sizes:
|
|
*
|
|
* Transmit status FIFO overflow
|
|
* PayloadSize = 1
|
|
* FramesToLoopback = 1000
|
|
*
|
|
* Transmit packet FIFO overflow
|
|
* PayloadSize = 1500
|
|
* FramesToLoopback = 16
|
|
*
|
|
* These values should always work without error
|
|
* PayloadSize = 100
|
|
* FramesToLoopback = 5
|
|
*/
|
|
PayloadSize = 100;
|
|
FramesToLoopback = 5;
|
|
|
|
/*
|
|
* Setup the transmit packet
|
|
*/
|
|
AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
|
|
AxiEthernetUtilFrameHdrFormatType(&TxFrame, PayloadSize);
|
|
AxiEthernetUtilFrameSetPayloadData(&TxFrame, PayloadSize);
|
|
|
|
/*
|
|
* Calculate frame length (not including FCS)
|
|
*/
|
|
TxFrameLength = XAE_HDR_SIZE + PayloadSize;
|
|
|
|
/****************/
|
|
/* Setup device */
|
|
/****************/
|
|
|
|
/*
|
|
* Start the device
|
|
*/
|
|
XAxiEthernet_Start(AxiEthernetInstancePtr);
|
|
|
|
/*
|
|
* Enable the interrupts
|
|
*/
|
|
XLlFifo_IntEnable(FifoInstancePtr, XLLF_INT_ALL_MASK);
|
|
|
|
|
|
/****************/
|
|
/* Send packets */
|
|
/****************/
|
|
|
|
/*
|
|
* Since we may be interested to see what happens when FIFOs overflow,
|
|
* don't check for room in the transmit packet FIFO prior to writing
|
|
* to it.
|
|
*/
|
|
|
|
/*
|
|
* With the xps_ll_fifo core we can't stuff the fifo with data from
|
|
* multiple packets and then send them. Instead, the code needs to
|
|
* write the data, and then immediately send the packet before
|
|
* writting the data for the next packet.
|
|
*/
|
|
for (Index = 0; Index < FramesToLoopback; Index++) {
|
|
/*
|
|
* Write frame data to FIFO
|
|
*/
|
|
XLlFifo_Write(FifoInstancePtr, TxFrame, TxFrameLength);
|
|
/*
|
|
* Initiate the transmission
|
|
*/
|
|
XLlFifo_TxSetLen(FifoInstancePtr, TxFrameLength);
|
|
}
|
|
|
|
/*******************/
|
|
/* Receive packets */
|
|
/*******************/
|
|
|
|
/*
|
|
* Now wait for frames to be received. When the callback is executed,
|
|
* it will disable interrupts and set a shared variable which will
|
|
* trigger this routine to process received frames
|
|
*/
|
|
for (Index = 0; Index < FramesToLoopback; Index++) {
|
|
/*
|
|
* Wait
|
|
*/
|
|
while (FramesRxInts == 0);
|
|
|
|
/*
|
|
* Frame has arrived, so get the length
|
|
*/
|
|
RxFrameLength = XLlFifo_RxGetLen(FifoInstancePtr);
|
|
|
|
/*
|
|
* Decision time: We can re-enable receive interrupts here or
|
|
* after we read the frame out of the FIFO. This is a matter
|
|
* of preference and goals of an application using the driver.
|
|
*/
|
|
XLlFifo_IntEnable(FifoInstancePtr, XLLF_INT_RC_MASK);
|
|
|
|
/*
|
|
* Frame size as expected?
|
|
*/
|
|
if ((RxFrameLength) != TxFrameLength) {
|
|
AxiEthernetUtilErrorTrap("Receive length incorrect");
|
|
}
|
|
|
|
/*
|
|
* Clear out receive packet memory area
|
|
*/
|
|
AxiEthernetUtilFrameMemClear(&RxFrame);
|
|
|
|
/*
|
|
* Read frame from packet FIFO
|
|
*/
|
|
XLlFifo_Read(FifoInstancePtr, &RxFrame, RxFrameLength);
|
|
/*
|
|
* Verify the received data
|
|
*/
|
|
if (AxiEthernetUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
|
|
AxiEthernetUtilErrorTrap("Data mismatch");
|
|
return XST_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Stop the device
|
|
*/
|
|
XAxiEthernet_Stop(AxiEthernetInstancePtr);
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the Receive handler callback function for examples 1 and 2.
|
|
* It will increment a shared counter, receive and validate the frame.
|
|
*
|
|
* @param Fifo is a reference to the Fifo device instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static void FifoRecvHandler(XLlFifo *Fifo)
|
|
{
|
|
u32 FrameLength;
|
|
|
|
/*
|
|
* We get the interrupt only once for multiple frames received.
|
|
* So get all the frames we can.
|
|
*/
|
|
/* While there is data in the fifo ... */
|
|
while (XLlFifo_RxOccupancy(Fifo)) {
|
|
/*
|
|
* Get the packet length
|
|
*/
|
|
FrameLength = XLlFifo_RxGetLen(Fifo);
|
|
|
|
XLlFifo_Read(Fifo, RxFrame, FrameLength);
|
|
/*
|
|
* Validate the packet data against the header of the TxFrame.
|
|
* The payload data should as placed by
|
|
* AxiEthernetUtilFrameSetPayloadData()
|
|
*/
|
|
if (AxiEthernetUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
|
|
FrameDataErrors++;
|
|
AxiEthernetUtilErrorTrap("Data mismatch");
|
|
return;
|
|
}
|
|
/*
|
|
* Bump counter
|
|
*/
|
|
FramesRx++;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the Error handler callback function and this function increments the
|
|
* the error counter so that the main thread knows the number of errors.
|
|
*
|
|
* @param Fifo is a reference to the AxiEthernet device instance.
|
|
*
|
|
* @param Pending is a bitmask of the pending interrupts.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static void FifoErrorHandler(XLlFifo *Fifo, u32 Pending)
|
|
{
|
|
int timeout_counter;
|
|
|
|
if (Pending & XLLF_INT_RPURE_MASK) {
|
|
AxiEthernetUtilErrorTrap("Fifo: Rx under-read error");
|
|
}
|
|
if (Pending & XLLF_INT_RPORE_MASK) {
|
|
AxiEthernetUtilErrorTrap("Fifo: Rx over-read error");
|
|
}
|
|
if (Pending & XLLF_INT_RPUE_MASK) {
|
|
AxiEthernetUtilErrorTrap("Fifo: Rx fifo empty");
|
|
}
|
|
if (Pending & XLLF_INT_TPOE_MASK) {
|
|
AxiEthernetUtilErrorTrap("Fifo: Tx fifo overrun");
|
|
}
|
|
if (Pending & XLLF_INT_TSE_MASK) {
|
|
AxiEthernetUtilErrorTrap("Fifo: Tx length mismatch");
|
|
}
|
|
|
|
/*
|
|
* Reset the tx or rx side of the fifo as needed
|
|
*/
|
|
if (Pending & XLLF_INT_RXERROR_MASK) {
|
|
XLlFifo_IntClear(Fifo, XLLF_INT_RRC_MASK);
|
|
XLlFifo_RxReset(Fifo);
|
|
|
|
timeout_counter = 10000;
|
|
|
|
while ((XLlFifo_Status(Fifo) & XLLF_INT_RRC_MASK) == 0) {
|
|
timeout_counter--;
|
|
if (timeout_counter == 0) {
|
|
XLlFifo_Reset(Fifo);
|
|
/* we've reset the whole core so just exit out */
|
|
goto feh_exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Pending & XLLF_INT_TXERROR_MASK) {
|
|
XLlFifo_IntClear(Fifo, XLLF_INT_TRC_MASK);
|
|
XLlFifo_TxReset(Fifo);
|
|
|
|
timeout_counter = 10000;
|
|
|
|
while ((XLlFifo_Status(Fifo) & XLLF_INT_TRC_MASK) == 0) {
|
|
timeout_counter--;
|
|
if (timeout_counter == 0) {
|
|
XLlFifo_Reset(Fifo);
|
|
|
|
/* we've reset the whole core so just exit out */
|
|
goto feh_exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
feh_exit:
|
|
/*
|
|
* Bump counter
|
|
*/
|
|
DeviceErrors++;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the Fifo handler function and will increment a shared
|
|
* counter that can be tested by the main thread of operation.
|
|
*
|
|
* @param Fifo is a reference to the Fifo instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static void FifoHandler(XLlFifo *Fifo)
|
|
{
|
|
u32 Pending = XLlFifo_IntPending(Fifo);
|
|
|
|
while (Pending) {
|
|
if (Pending & XLLF_INT_RC_MASK) {
|
|
/*
|
|
* Receive the frame, unless we are deferring the
|
|
* receive.
|
|
*/
|
|
if (DeferRx) {
|
|
FramesRxInts++; /* We can count the interrupts,
|
|
* but in the handler we don't
|
|
* exactly know how many frames
|
|
* as we could get one int for
|
|
* multiple frames.
|
|
*/
|
|
/*
|
|
* use for example 3: Disable receive
|
|
* interrupts to defer frame reception
|
|
* to the example function.
|
|
*/
|
|
XLlFifo_IntDisable(Fifo, XLLF_INT_RC_MASK);
|
|
}
|
|
else {
|
|
FifoRecvHandler(Fifo);
|
|
}
|
|
XLlFifo_IntClear(Fifo, XLLF_INT_RC_MASK);
|
|
}
|
|
else if (Pending & XLLF_INT_TC_MASK) {
|
|
FramesTxInts++; /* We can count the interrupts, but in
|
|
* the handler we don't exactly know
|
|
* how many frames as we could get one
|
|
* int for multiple frames.
|
|
*/
|
|
XLlFifo_IntClear(Fifo, XLLF_INT_TC_MASK);
|
|
}
|
|
else if (Pending & XLLF_INT_ERROR_MASK){
|
|
FifoErrorHandler(Fifo, Pending);
|
|
XLlFifo_IntClear(Fifo, XLLF_INT_ERROR_MASK);
|
|
} else {
|
|
XLlFifo_IntClear(Fifo, Pending);
|
|
}
|
|
Pending = XLlFifo_IntPending(Fifo);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This is the Error handler callback function and this function increments the
|
|
* the error counter so that the main thread knows the number of errors.
|
|
*
|
|
* @param AxiEthernet is a reference to the AxiEthernet device instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static void AxiEthernetErrorHandler(XAxiEthernet *AxiEthernet)
|
|
{
|
|
u32 Pending = XAxiEthernet_IntPending(AxiEthernet);
|
|
|
|
if (Pending & XAE_INT_RXRJECT_MASK) {
|
|
AxiEthernetUtilErrorTrap("AxiEthernet: Rx packet rejected");
|
|
}
|
|
if (Pending & XAE_INT_RXFIFOOVR_MASK) {
|
|
AxiEthernetUtilErrorTrap("AxiEthernet: Rx fifo over run");
|
|
}
|
|
XAxiEthernet_IntClear(AxiEthernet, Pending);
|
|
|
|
/*
|
|
* Bump counter
|
|
*/
|
|
DeviceErrors++;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/**
|
|
* This function resets the device but preserves the options set by the user.
|
|
*
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* AxiEthernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the Fifo
|
|
* component.
|
|
*
|
|
* @return - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static int AxiEthernetResetDevice(XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr)
|
|
{
|
|
int Status;
|
|
u8 MacSave[6];
|
|
u32 Options;
|
|
|
|
/*
|
|
* Stop the Axi Ethernet device
|
|
*/
|
|
XAxiEthernet_Stop(AxiEthernetInstancePtr);
|
|
|
|
|
|
/*
|
|
* Save the device state
|
|
*/
|
|
XAxiEthernet_GetMacAddress(AxiEthernetInstancePtr, MacSave);
|
|
Options = XAxiEthernet_GetOptions(AxiEthernetInstancePtr);
|
|
|
|
/*
|
|
* Stop and reset the Axi Ethernet device
|
|
*/
|
|
XAxiEthernet_Reset(AxiEthernetInstancePtr);
|
|
|
|
/*
|
|
* reset the fifo
|
|
*/
|
|
XLlFifo_Reset(FifoInstancePtr);
|
|
|
|
/*
|
|
* Restore the state
|
|
*/
|
|
Status = XAxiEthernet_SetMacAddress(AxiEthernetInstancePtr, MacSave);
|
|
Status |= XAxiEthernet_SetOptions(AxiEthernetInstancePtr, Options);
|
|
Status |= XAxiEthernet_ClearOptions(AxiEthernetInstancePtr, ~Options);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Error restoring state after reset");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Restart the device
|
|
*/
|
|
XAxiEthernet_Start(AxiEthernetInstancePtr);
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function setups the interrupt system so interrupts can occur for the
|
|
* Axi Ethernet. This function is application-specific since the actual system
|
|
* may or may not have an interrupt controller. The Axi Ethernet 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 component.
|
|
* @param AxiEthernetInstancePtr is a pointer to the instance of the
|
|
* AxiEthernet component.
|
|
* @param FifoInstancePtr is a pointer to the instance of the AXIFIFO
|
|
* component.
|
|
* @param AxiEthernetDeviceId is Device ID of the Axi Ethernet Device ,
|
|
* typically XPAR_<AXIETHERNET_instance>_DEVICE_ID value from
|
|
* xparameters.h.
|
|
* @param AxiEthernetIntrId is the Interrupt ID and is typically
|
|
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
|
|
* value from xparameters.h.
|
|
* @param FifoIntrId is the interrupt id fifo.
|
|
*
|
|
* @return - XST_SUCCESS to indicate success.
|
|
* - XST_FAILURE.to indicate failure.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static int AxiEthernetSetupIntrSystem(INTC *IntcInstancePtr,
|
|
XAxiEthernet *AxiEthernetInstancePtr,
|
|
XLlFifo *FifoInstancePtr,
|
|
u16 AxiEthernetIntrId, u16 FifoIntrId)
|
|
{
|
|
int Status;
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
#ifndef TESTAPP_GEN
|
|
/*
|
|
* Initialize the interrupt controller and connect the ISR
|
|
*/
|
|
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap
|
|
("Unable to intialize the interrupt controller");
|
|
return XST_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
#if XPAR_INTC_0_HAS_FAST == 1
|
|
AxiEthernetInstancePtr_Fast = AxiEthernetInstancePtr;
|
|
Fifo_Fast = FifoInstancePtr;
|
|
Status = XIntc_ConnectFastHandler(IntcInstancePtr, AxiEthernetIntrId,
|
|
(XFastInterruptHandler) AxiEthernetErrorFastHandler);
|
|
Status |= XIntc_ConnectFastHandler(IntcInstancePtr, FifoIntrId,
|
|
(XFastInterruptHandler) FifoFastHandler);
|
|
#else
|
|
Status = XIntc_Connect(IntcInstancePtr, AxiEthernetIntrId,
|
|
(XInterruptHandler) AxiEthernetErrorHandler,
|
|
AxiEthernetInstancePtr);
|
|
Status |= XIntc_Connect(IntcInstancePtr, FifoIntrId,
|
|
(XInterruptHandler) FifoHandler,
|
|
FifoInstancePtr);
|
|
#endif
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap
|
|
("Unable to connect ISR to interrupt controller");
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
#ifndef TESTAPP_GEN
|
|
/*
|
|
* Start the interrupt controller
|
|
*/
|
|
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
|
|
if (Status != XST_SUCCESS) {
|
|
AxiEthernetUtilErrorTrap("Error starting intc");
|
|
return XST_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Enable interrupts from the hardware
|
|
*/
|
|
XIntc_Enable(IntcInstancePtr, AxiEthernetIntrId);
|
|
XIntc_Enable(IntcInstancePtr, FifoIntrId);
|
|
#else
|
|
XScuGic_Config *IntcConfig;
|
|
|
|
/*
|
|
* Initialize the interrupt controller driver so that it is ready to
|
|
* use.
|
|
*/
|
|
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
|
|
if (NULL == IntcConfig) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
|
|
IntcConfig->CpuBaseAddress);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
|
|
XScuGic_SetPriorityTriggerType(IntcInstancePtr, FifoIntrId, 0xA0, 0x3);
|
|
|
|
XScuGic_SetPriorityTriggerType(IntcInstancePtr, AxiEthernetIntrId, 0xA0, 0x3);
|
|
/*
|
|
* Connect the device driver handler that will be called when an
|
|
* interrupt for the device occurs, the handler defined above performs
|
|
* the specific interrupt processing for the device.
|
|
*/
|
|
Status = XScuGic_Connect(IntcInstancePtr, FifoIntrId,
|
|
(Xil_InterruptHandler)FifoHandler,
|
|
FifoInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
Status = XScuGic_Connect(IntcInstancePtr, AxiEthernetIntrId,
|
|
(Xil_InterruptHandler)AxiEthernetErrorHandler,
|
|
AxiEthernetInstancePtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
XScuGic_Enable(IntcInstancePtr, AxiEthernetIntrId);
|
|
XScuGic_Enable(IntcInstancePtr, FifoIntrId);
|
|
#endif
|
|
#ifndef TESTAPP_GEN
|
|
|
|
Xil_ExceptionInit();
|
|
|
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
|
(Xil_ExceptionHandler)INTC_HANDLER,
|
|
(void *)(IntcInstancePtr));
|
|
|
|
Xil_ExceptionEnable();
|
|
|
|
#endif
|
|
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* This function disables the interrupts that occur for AxiEthernet.
|
|
*
|
|
* @param IntcInstancePtr is a pointer to the instance of the Intc
|
|
* component.
|
|
* @param AxiEthernetIntrId is the Interrupt ID and is typically
|
|
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
|
|
* value from xparameters.h.
|
|
* @param FifoIntrId is the interrupt id for fifo.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
static void AxiEthernetDisableIntrSystem(INTC *IntcInstancePtr,
|
|
u16 AxiEthernetIntrId, u16 FifoIntrId)
|
|
{
|
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
|
/*
|
|
* Disconnect and disable the interrupt for the AxiEthernet device
|
|
*/
|
|
XIntc_Disconnect(IntcInstancePtr, AxiEthernetIntrId);
|
|
/*
|
|
* Disconnect and disable the interrupt for the Fifo device
|
|
*/
|
|
XIntc_Disconnect(IntcInstancePtr, FifoIntrId);
|
|
|
|
#else
|
|
/*
|
|
* Disconnect and disable the interrupt for the AxiEthernet device
|
|
*/
|
|
XScuGic_Disconnect(IntcInstancePtr, AxiEthernetIntrId);
|
|
/*
|
|
* Disconnect and disable the interrupt for the Fifo device
|
|
*/
|
|
XScuGic_Disconnect(IntcInstancePtr, FifoIntrId);
|
|
#endif
|
|
}
|
|
|
|
#if XPAR_INTC_0_HAS_FAST == 1
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* Fast Error Handler which calls AxiEthernetErrorHandler.
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void AxiEthernetErrorFastHandler(void)
|
|
{
|
|
AxiEthernetErrorHandler((XAxiEthernet *)AxiEthernetInstancePtr_Fast);
|
|
}
|
|
/*****************************************************************************/
|
|
/**
|
|
*
|
|
* Fast FIFO Handler which calls FifoHandler.
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void FifoFastHandler(void)
|
|
{
|
|
FifoHandler((XLlFifo *)Fifo_Fast);
|
|
}
|
|
|
|
#endif
|