575 lines
18 KiB
C
575 lines
18 KiB
C
![]() |
/******************************************************************************
|
||
|
*
|
||
|
* 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 xusbps_intr_example.c
|
||
|
*
|
||
|
* This file contains an example of how to use the USB driver with the USB
|
||
|
* controller in DEVICE mode.
|
||
|
*
|
||
|
*
|
||
|
*<pre>
|
||
|
* MODIFICATION HISTORY:
|
||
|
*
|
||
|
* Ver Who Date Changes
|
||
|
* ----- ------ -------- ----------------------------------------------------
|
||
|
* 1.00a wgr/nm 10/09/10 First release
|
||
|
* 1.01a nm 03/05/10 Included xpseudo_asm.h instead of xpseudo_asm_gcc.h
|
||
|
* 1.04a nm 02/05/13 Fixed CR# 696550.
|
||
|
* Added template code for Vendor request.
|
||
|
* 1.06a kpc 11/11/13 Fixed CR#759458, cacheInvalidate size should be
|
||
|
* ailgned to ccahe line size.
|
||
|
* 2.1 kpc 04/28/14 Cleanup and removed unused functions
|
||
|
*</pre>
|
||
|
******************************************************************************/
|
||
|
|
||
|
/***************************** Include Files *********************************/
|
||
|
|
||
|
#include "xparameters.h" /* XPAR parameters */
|
||
|
#include "xusbps.h" /* USB controller driver */
|
||
|
#include "xscugic.h"
|
||
|
#include "xusbps_ch9.h" /* Generic Chapter 9 handling code */
|
||
|
#include "xusbps_class_storage.h" /* Storage class handling code */
|
||
|
#include "xil_exception.h"
|
||
|
#include "xpseudo_asm.h"
|
||
|
#include "xreg_cortexa9.h"
|
||
|
#include "xil_cache.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/************************** Constant Definitions *****************************/
|
||
|
#define MEMORY_SIZE (64 * 1024)
|
||
|
u8 Buffer[MEMORY_SIZE] ALIGNMENT_CACHELINE;
|
||
|
|
||
|
/**************************** Type Definitions *******************************/
|
||
|
|
||
|
/***************** Macros (Inline Functions) Definitions *********************/
|
||
|
|
||
|
/************************** Function Prototypes ******************************/
|
||
|
|
||
|
static int UsbIntrExample(XScuGic *IntcInstancePtr, XUsbPs *UsbInstancePtr,
|
||
|
u16 UsbDeviceId, u16 UsbIntrId);
|
||
|
|
||
|
static void UsbIntrHandler(void *CallBackRef, u32 Mask);
|
||
|
static void XUsbPs_Ep0EventHandler(void *CallBackRef, u8 EpNum,
|
||
|
u8 EventType, void *Data);
|
||
|
static void XUsbPs_Ep1EventHandler(void *CallBackRef, u8 EpNum,
|
||
|
u8 EventType, void *Data);
|
||
|
static int UsbSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||
|
XUsbPs *UsbInstancePtr, u16 UsbIntrId);
|
||
|
static void UsbDisableIntrSystem(XScuGic *IntcInstancePtr, u16 UsbIntrId);
|
||
|
|
||
|
|
||
|
/************************** Variable Definitions *****************************/
|
||
|
|
||
|
/* The instances to support the device drivers are global such that the
|
||
|
* are initialized to zero each time the program runs.
|
||
|
*/
|
||
|
static XScuGic IntcInstance; /* The instance of the IRQ Controller */
|
||
|
static XUsbPs UsbInstance; /* The instance of the USB Controller */
|
||
|
|
||
|
static volatile int NumIrqs = 0;
|
||
|
static volatile int NumReceivedFrames = 0;
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* Main function to call the USB interrupt example.
|
||
|
*
|
||
|
* @param None
|
||
|
*
|
||
|
* @return
|
||
|
* - XST_SUCCESS if successful
|
||
|
* - XST_FAILURE on error
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
int Status;
|
||
|
|
||
|
/* Run the USB Interrupt example.*/
|
||
|
Status = UsbIntrExample(&IntcInstance, &UsbInstance,
|
||
|
XPAR_XUSBPS_0_DEVICE_ID, XPAR_XUSBPS_0_INTR);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function does a minimal DEVICE mode setup on the USB device and driver
|
||
|
* as a design example. The purpose of this function is to illustrate how to
|
||
|
* set up a USB flash disk emulation system.
|
||
|
*
|
||
|
*
|
||
|
* @param IntcInstancePtr is a pointer to the instance of the INTC driver.
|
||
|
* @param UsbInstancePtr is a pointer to the instance of USB driver.
|
||
|
* @param UsbDeviceId is the Device ID of the USB Controller and is the
|
||
|
* XPAR_<USB_instance>_DEVICE_ID value from xparameters.h.
|
||
|
* @param UsbIntrId is the Interrupt Id and is typically
|
||
|
* XPAR_<INTC_instance>_<USB_instance>_IP2INTC_IRPT_INTR value
|
||
|
* from xparameters.h.
|
||
|
*
|
||
|
* @return
|
||
|
* - XST_SUCCESS if successful
|
||
|
* - XST_FAILURE on error
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static int UsbIntrExample(XScuGic *IntcInstancePtr, XUsbPs *UsbInstancePtr,
|
||
|
u16 UsbDeviceId, u16 UsbIntrId)
|
||
|
{
|
||
|
int Status;
|
||
|
u8 *MemPtr = NULL;
|
||
|
int ReturnStatus = XST_FAILURE;
|
||
|
|
||
|
/* For this example we only configure 2 endpoints:
|
||
|
* Endpoint 0 (default control endpoint)
|
||
|
* Endpoint 1 (BULK data endpoint)
|
||
|
*/
|
||
|
const u8 NumEndpoints = 2;
|
||
|
|
||
|
XUsbPs_Config *UsbConfigPtr;
|
||
|
XUsbPs_DeviceConfig DeviceConfig;
|
||
|
|
||
|
/* Initialize the USB driver so that it's ready to use,
|
||
|
* specify the controller ID that is generated in xparameters.h
|
||
|
*/
|
||
|
UsbConfigPtr = XUsbPs_LookupConfig(UsbDeviceId);
|
||
|
if (NULL == UsbConfigPtr) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* We are passing the physical base address as the third argument
|
||
|
* because the physical and virtual base address are the same in our
|
||
|
* example. For systems that support virtual memory, the third
|
||
|
* argument needs to be the virtual base address.
|
||
|
*/
|
||
|
Status = XUsbPs_CfgInitialize(UsbInstancePtr,
|
||
|
UsbConfigPtr,
|
||
|
UsbConfigPtr->BaseAddress);
|
||
|
if (XST_SUCCESS != Status) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
/* Set up the interrupt subsystem.
|
||
|
*/
|
||
|
Status = UsbSetupIntrSystem(IntcInstancePtr,
|
||
|
UsbInstancePtr,
|
||
|
UsbIntrId);
|
||
|
if (XST_SUCCESS != Status)
|
||
|
{
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
/* Configuration of the DEVICE side of the controller happens in
|
||
|
* multiple stages.
|
||
|
*
|
||
|
* 1) The user configures the desired endpoint configuration using the
|
||
|
* XUsbPs_DeviceConfig data structure. This includes the number of
|
||
|
* endpoints, the number of Transfer Descriptors for each endpoint
|
||
|
* (each endpoint can have a different number of Transfer Descriptors)
|
||
|
* and the buffer size for the OUT (receive) endpoints. Each endpoint
|
||
|
* can have different buffer sizes.
|
||
|
*
|
||
|
* 2) Request the required size of DMAable memory from the driver using
|
||
|
* the XUsbPs_DeviceMemRequired() call.
|
||
|
*
|
||
|
* 3) Allocate the DMAable memory and set up the DMAMemVirt and
|
||
|
* DMAMemPhys members in the XUsbPs_DeviceConfig data structure.
|
||
|
*
|
||
|
* 4) Configure the DEVICE side of the controller by calling the
|
||
|
* XUsbPs_ConfigureDevice() function.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* For this example we only configure Endpoint 0 and Endpoint 1.
|
||
|
*
|
||
|
* Bufsize = 0 indicates that there is no buffer allocated for OUT
|
||
|
* (receive) endpoint 0. Endpoint 0 is a control endpoint and we only
|
||
|
* receive control packets on that endpoint. Control packets are 8
|
||
|
* bytes in size and are received into the Queue Head's Setup Buffer.
|
||
|
* Therefore, no additional buffer space is needed.
|
||
|
*/
|
||
|
DeviceConfig.EpCfg[0].Out.Type = XUSBPS_EP_TYPE_CONTROL;
|
||
|
DeviceConfig.EpCfg[0].Out.NumBufs = 2;
|
||
|
DeviceConfig.EpCfg[0].Out.BufSize = 64;
|
||
|
DeviceConfig.EpCfg[0].Out.MaxPacketSize = 64;
|
||
|
DeviceConfig.EpCfg[0].In.Type = XUSBPS_EP_TYPE_CONTROL;
|
||
|
DeviceConfig.EpCfg[0].In.NumBufs = 2;
|
||
|
DeviceConfig.EpCfg[0].In.MaxPacketSize = 64;
|
||
|
|
||
|
DeviceConfig.EpCfg[1].Out.Type = XUSBPS_EP_TYPE_BULK;
|
||
|
DeviceConfig.EpCfg[1].Out.NumBufs = 16;
|
||
|
DeviceConfig.EpCfg[1].Out.BufSize = 512;
|
||
|
DeviceConfig.EpCfg[1].Out.MaxPacketSize = 512;
|
||
|
DeviceConfig.EpCfg[1].In.Type = XUSBPS_EP_TYPE_BULK;
|
||
|
DeviceConfig.EpCfg[1].In.NumBufs = 16;
|
||
|
DeviceConfig.EpCfg[1].In.MaxPacketSize = 512;
|
||
|
|
||
|
DeviceConfig.NumEndpoints = NumEndpoints;
|
||
|
|
||
|
MemPtr = (u8 *)&Buffer[0];
|
||
|
memset(MemPtr,0,MEMORY_SIZE);
|
||
|
Xil_DCacheFlushRange((unsigned int)MemPtr, MEMORY_SIZE);
|
||
|
|
||
|
/* Finish the configuration of the DeviceConfig structure and configure
|
||
|
* the DEVICE side of the controller.
|
||
|
*/
|
||
|
DeviceConfig.DMAMemPhys = (u32) MemPtr;
|
||
|
|
||
|
Status = XUsbPs_ConfigureDevice(UsbInstancePtr, &DeviceConfig);
|
||
|
if (XST_SUCCESS != Status) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
/* Set the handler for receiving frames. */
|
||
|
Status = XUsbPs_IntrSetHandler(UsbInstancePtr, UsbIntrHandler, NULL,
|
||
|
XUSBPS_IXR_UE_MASK);
|
||
|
if (XST_SUCCESS != Status) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
/* Set the handler for handling endpoint 0 events. This is where we
|
||
|
* will receive and handle the Setup packet from the host.
|
||
|
*/
|
||
|
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 0,
|
||
|
XUSBPS_EP_DIRECTION_OUT,
|
||
|
XUsbPs_Ep0EventHandler, UsbInstancePtr);
|
||
|
|
||
|
/* Set the handler for handling endpoint 1 events.
|
||
|
*
|
||
|
* Note that for this example we do not need to register a handler for
|
||
|
* TX complete events as we only send data using static data buffers
|
||
|
* that do not need to be free()d or returned to the OS after they have
|
||
|
* been sent.
|
||
|
*/
|
||
|
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 1,
|
||
|
XUSBPS_EP_DIRECTION_OUT,
|
||
|
XUsbPs_Ep1EventHandler, UsbInstancePtr);
|
||
|
|
||
|
/* Enable the interrupts. */
|
||
|
XUsbPs_IntrEnable(UsbInstancePtr, XUSBPS_IXR_UR_MASK |
|
||
|
XUSBPS_IXR_UI_MASK);
|
||
|
|
||
|
|
||
|
/* Start the USB engine */
|
||
|
XUsbPs_Start(UsbInstancePtr);
|
||
|
|
||
|
/* At this point we wait for the user to plug in the usb plug. This
|
||
|
* will cause the host to send USB packets. Once we received something,
|
||
|
* we clean up and stop the controller.
|
||
|
*
|
||
|
* This will not really work if we want to use the USB storage
|
||
|
* example. What can we do instead?
|
||
|
*/
|
||
|
while (NumReceivedFrames < 1) {
|
||
|
/* NOP */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Set return code to indicate success and fall through to clean-up
|
||
|
* code.
|
||
|
*/
|
||
|
ReturnStatus = XST_SUCCESS;
|
||
|
|
||
|
out:
|
||
|
/* Clean up. It's always safe to disable interrupts and clear the
|
||
|
* handlers, even if they have not been enabled/set. The same is true
|
||
|
* for disabling the interrupt subsystem.
|
||
|
*/
|
||
|
XUsbPs_Stop(UsbInstancePtr);
|
||
|
XUsbPs_IntrDisable(UsbInstancePtr, XUSBPS_IXR_ALL);
|
||
|
(int) XUsbPs_IntrSetHandler(UsbInstancePtr, NULL, NULL, 0);
|
||
|
|
||
|
UsbDisableIntrSystem(IntcInstancePtr, UsbIntrId);
|
||
|
|
||
|
/* Free allocated memory.
|
||
|
*/
|
||
|
if (NULL != UsbInstancePtr->UserDataPtr) {
|
||
|
free(UsbInstancePtr->UserDataPtr);
|
||
|
}
|
||
|
return ReturnStatus;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function is the handler which performs processing for the USB driver.
|
||
|
* It is called from an interrupt context such that the amount of processing
|
||
|
* performed should be minimized.
|
||
|
*
|
||
|
* This handler provides an example of how to handle USB interrupts and
|
||
|
* is application specific.
|
||
|
*
|
||
|
* @param CallBackRef is the Upper layer callback reference passed back
|
||
|
* when the callback function is invoked.
|
||
|
* @param Mask is the Interrupt Mask.
|
||
|
* @param CallBackRef is the User data reference.
|
||
|
*
|
||
|
* @return
|
||
|
* - XST_SUCCESS if successful
|
||
|
* - XST_FAILURE on error
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void UsbIntrHandler(void *CallBackRef, u32 Mask)
|
||
|
{
|
||
|
NumIrqs++;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
* This funtion is registered to handle callbacks for endpoint 0 (Control).
|
||
|
*
|
||
|
* It is called from an interrupt context such that the amount of processing
|
||
|
* performed should be minimized.
|
||
|
*
|
||
|
*
|
||
|
* @param CallBackRef is the reference passed in when the function
|
||
|
* was registered.
|
||
|
* @param EpNum is the Number of the endpoint on which the event occured.
|
||
|
* @param EventType is type of the event that occured.
|
||
|
*
|
||
|
* @return None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void XUsbPs_Ep0EventHandler(void *CallBackRef, u8 EpNum,
|
||
|
u8 EventType, void *Data)
|
||
|
{
|
||
|
XUsbPs *InstancePtr;
|
||
|
int Status;
|
||
|
XUsbPs_SetupData SetupData;
|
||
|
u8 *BufferPtr;
|
||
|
u32 BufferLen;
|
||
|
u32 Handle;
|
||
|
|
||
|
|
||
|
Xil_AssertVoid(NULL != CallBackRef);
|
||
|
|
||
|
InstancePtr = (XUsbPs *) CallBackRef;
|
||
|
|
||
|
switch (EventType) {
|
||
|
|
||
|
/* Handle the Setup Packets received on Endpoint 0. */
|
||
|
case XUSBPS_EP_EVENT_SETUP_DATA_RECEIVED:
|
||
|
Status = XUsbPs_EpGetSetupData(InstancePtr, EpNum, &SetupData);
|
||
|
if (XST_SUCCESS == Status) {
|
||
|
/* Handle the setup packet. */
|
||
|
(int) XUsbPs_Ch9HandleSetupPacket(InstancePtr,
|
||
|
&SetupData);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
/* We get data RX events for 0 length packets on endpoint 0. We receive
|
||
|
* and immediately release them again here, but there's no action to be
|
||
|
* taken.
|
||
|
*/
|
||
|
case XUSBPS_EP_EVENT_DATA_RX:
|
||
|
/* Get the data buffer. */
|
||
|
Status = XUsbPs_EpBufferReceive(InstancePtr, EpNum,
|
||
|
&BufferPtr, &BufferLen, &Handle);
|
||
|
if (XST_SUCCESS == Status) {
|
||
|
/* Return the buffer. */
|
||
|
XUsbPs_EpBufferRelease(Handle);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
/* Unhandled event. Ignore. */
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
* This funtion is registered to handle callbacks for endpoint 1 (Bulk data).
|
||
|
*
|
||
|
* It is called from an interrupt context such that the amount of processing
|
||
|
* performed should be minimized.
|
||
|
*
|
||
|
*
|
||
|
* @param CallBackRef is the reference passed in when the function was
|
||
|
* registered.
|
||
|
* @param EpNum is the Number of the endpoint on which the event occured.
|
||
|
* @param EventType is type of the event that occured.
|
||
|
*
|
||
|
* @return None.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void XUsbPs_Ep1EventHandler(void *CallBackRef, u8 EpNum,
|
||
|
u8 EventType, void *Data)
|
||
|
{
|
||
|
XUsbPs *InstancePtr;
|
||
|
int Status;
|
||
|
u8 *BufferPtr;
|
||
|
u32 BufferLen;
|
||
|
u32 InavalidateLen;
|
||
|
u32 Handle;
|
||
|
|
||
|
|
||
|
Xil_AssertVoid(NULL != CallBackRef);
|
||
|
|
||
|
InstancePtr = (XUsbPs *) CallBackRef;
|
||
|
|
||
|
switch (EventType) {
|
||
|
case XUSBPS_EP_EVENT_DATA_RX:
|
||
|
/* Get the data buffer.*/
|
||
|
Status = XUsbPs_EpBufferReceive(InstancePtr, EpNum,
|
||
|
&BufferPtr, &BufferLen, &Handle);
|
||
|
/* Invalidate the Buffer Pointer */
|
||
|
InavalidateLen = BufferLen;
|
||
|
if (BufferLen % 32) {
|
||
|
InavalidateLen = (BufferLen/32) * 32 + 32;
|
||
|
}
|
||
|
|
||
|
Xil_DCacheInvalidateRange((unsigned int)BufferPtr,
|
||
|
InavalidateLen);
|
||
|
if (XST_SUCCESS == Status) {
|
||
|
/* Handle the storage class request. */
|
||
|
XUsbPs_HandleStorageReq(InstancePtr, EpNum,
|
||
|
BufferPtr, BufferLen);
|
||
|
/* Release the buffer. */
|
||
|
XUsbPs_EpBufferRelease(Handle);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
/* Unhandled event. Ignore. */
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function setups the interrupt system such that interrupts can occur for
|
||
|
* the USB controller. This function is application specific since the actual
|
||
|
* system may or may not have an interrupt controller. The USB controller 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 instance of the Intc controller.
|
||
|
* @param UsbInstancePtr is a pointer to instance of the USB controller.
|
||
|
* @param UsbIntrId is the Interrupt Id and is typically
|
||
|
* XPAR_<INTC_instance>_<USB_instance>_VEC_ID value
|
||
|
* from xparameters.h
|
||
|
*
|
||
|
* @return
|
||
|
* - XST_SUCCESS if successful
|
||
|
* - XST_FAILURE on error
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static int UsbSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||
|
XUsbPs *UsbInstancePtr, u16 UsbIntrId)
|
||
|
{
|
||
|
int Status;
|
||
|
XScuGic_Config *IntcConfig;
|
||
|
|
||
|
/*
|
||
|
* Initialize the interrupt controller driver so that it is ready to
|
||
|
* use.
|
||
|
*/
|
||
|
IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
|
||
|
if (NULL == IntcConfig) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
|
||
|
IntcConfig->CpuBaseAddress);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
Xil_ExceptionInit();
|
||
|
/*
|
||
|
* Connect the interrupt controller interrupt handler to the hardware
|
||
|
* interrupt handling logic in the processor.
|
||
|
*/
|
||
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
||
|
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||
|
IntcInstancePtr);
|
||
|
/*
|
||
|
* 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, UsbIntrId,
|
||
|
(Xil_ExceptionHandler)XUsbPs_IntrHandler,
|
||
|
(void *)UsbInstancePtr);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return Status;
|
||
|
}
|
||
|
/*
|
||
|
* Enable the interrupt for the device.
|
||
|
*/
|
||
|
XScuGic_Enable(IntcInstancePtr, UsbIntrId);
|
||
|
|
||
|
/*
|
||
|
* Enable interrupts in the Processor.
|
||
|
*/
|
||
|
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/**
|
||
|
*
|
||
|
* This function disables the interrupts that occur for the USB controller.
|
||
|
*
|
||
|
* @param IntcInstancePtr is a pointer to instance of the INTC driver.
|
||
|
* @param UsbIntrId is the Interrupt Id and is typically
|
||
|
* XPAR_<INTC_instance>_<USB_instance>_VEC_ID value
|
||
|
* from xparameters.h
|
||
|
*
|
||
|
* @return None
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void UsbDisableIntrSystem(XScuGic *IntcInstancePtr, u16 UsbIntrId)
|
||
|
{
|
||
|
/* Disconnect and disable the interrupt for the USB controller. */
|
||
|
XScuGic_Disconnect(IntcInstancePtr, UsbIntrId);
|
||
|
}
|