570 lines
17 KiB
C
570 lines
17 KiB
C
![]() |
/******************************************************************************
|
||
|
*
|
||
|
* Copyright (C) 2002 - 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 xgpio_intr_example.c
|
||
|
*
|
||
|
* This file contains a design example using the GPIO driver (XGpio) in an
|
||
|
* interrupt driven mode of operation. This example does assume that there is
|
||
|
* an interrupt controller in the hardware system and the GPIO device is
|
||
|
* connected to the interrupt controller.
|
||
|
*
|
||
|
* This example is designed to work on the Xilinx ML300 board using the PowerPC
|
||
|
* 405 processor present in the VirtexIIPro device. The example uses the
|
||
|
* interrupt capability of the GPIO to detect push button presses and control the
|
||
|
* LEDs on the board. When a button is pressed it will turn on and LED located
|
||
|
* closest to it. When the button is released it will turn off the LED.
|
||
|
* This examples uses two channels of a GPIO such that it is necessary to have
|
||
|
* dual channel capabilities.
|
||
|
*
|
||
|
* The buttons and LEDs are on 2 seperate channels of the GPIO so that interrupts
|
||
|
* are not caused when the LEDs are turned on and off.
|
||
|
*
|
||
|
* At the start of execution all LEDs will be turned on, then each one by itself,
|
||
|
* and then all on again followed by all turned off. After this sequence, button
|
||
|
* presses are processed by interrupts.
|
||
|
*
|
||
|
* The following snippet from the UCF file of the hardware build indicates the
|
||
|
* way the GPIO channels are connected to the ML300 for the LEDs and buttons.
|
||
|
*
|
||
|
*<pre>
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<0> LOC=C4;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<1> LOC=L8;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<2> LOC=F8;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<3> LOC=J7;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<4> LOC=K7;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<5> LOC=E7;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<6> LOC=D3;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<7> LOC=C6;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<8> LOC=E8;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<9> LOC=B3;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<10> LOC=E9;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<11> LOC=G9;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<12> LOC=A3;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<13> LOC=F9;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<14> LOC=D6;
|
||
|
* Net LEDs_Push_Buttons_GPIO_IO<15> LOC=G10;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<0> LOC=G6;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<1> LOC=L7;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<2> LOC=G5;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<3> LOC=M8;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<4> LOC=H6;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<5> LOC=M7;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<6> LOC=H5;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<7> LOC=N8;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<8> LOC=J6;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<9> LOC=M5;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<10> LOC=J5;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<11> LOC=M2;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<12> LOC=K6;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<13> LOC=M1;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<14> LOC=K5;
|
||
|
* Net LEDs_Push_Buttons_GPIO2_IO<15> LOC=P6;
|
||
|
*
|
||
|
* MODIFICATION HISTORY:
|
||
|
*
|
||
|
* Ver Who Date Changes
|
||
|
* ----- ---- -------- -----------------------------------------------
|
||
|
* 2.00a jhl 12/01/03 First release
|
||
|
* 2.00a sv 04/15/05 Minor changes to comply to Doxygen and coding guidelines
|
||
|
* 3.00a ktn 11/21/09 Updated to use HAL Processor APIs and minior changes
|
||
|
* as per coding guidelines.
|
||
|
* 3.00a sdm 02/16/11 Updated to support ARM Generic Interrupt Controller
|
||
|
*</pre>
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
/***************************** Include Files *********************************/
|
||
|
|
||
|
#include "xparameters.h"
|
||
|
#include "xgpio.h"
|
||
|
#include "xil_exception.h"
|
||
|
|
||
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
||
|
#include "xintc.h"
|
||
|
#else
|
||
|
#include "xscugic.h"
|
||
|
#endif
|
||
|
|
||
|
/************************** Constant Definitions *****************************/
|
||
|
|
||
|
/*
|
||
|
* The following constants map to the names of the hardware instances that
|
||
|
* were created in the EDK XPS system. They are only defined here such that
|
||
|
* a user can easily change all the needed device IDs in one place.
|
||
|
*/
|
||
|
#define GPIO_DEVICE_ID XPAR_PUSH_BUTTONS_4BITS_DEVICE_ID
|
||
|
#define INTC_GPIO_INTERRUPT_ID XPAR_INTC_0_GPIO_2_VEC_ID
|
||
|
|
||
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
||
|
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
|
||
|
#define INTC XIntc
|
||
|
#define INTC_HANDLER XIntc_InterruptHandler
|
||
|
#else
|
||
|
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||
|
#define INTC XScuGic
|
||
|
#define INTC_HANDLER XScuGic_InterruptHandler
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* The following constants define the positions of the buttons and LEDs each
|
||
|
* channel of the GPIO
|
||
|
*/
|
||
|
#define GPIO_ALL_LEDS 0xFFFF
|
||
|
#define GPIO_ALL_BUTTONS 0xFFFF
|
||
|
|
||
|
/*
|
||
|
* The following constants define the GPIO channel that is used for the buttons
|
||
|
* and the LEDs. They allow the channels to be reversed easily.
|
||
|
*/
|
||
|
#define BUTTON_CHANNEL 1 /* Channel 1 of the GPIO Device */
|
||
|
#define LED_CHANNEL 2 /* Channel 2 of the GPIO Device */
|
||
|
#define BUTTON_INTERRUPT XGPIO_IR_CH1_MASK /* Channel 1 Interrupt Mask */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* The following constant is used to wait after an LED is turned on to make
|
||
|
* sure that it is visible to the human eye. This constant might need to be
|
||
|
* tuned for faster or slower processor speeds.
|
||
|
*/
|
||
|
#define LED_DELAY 1000000
|
||
|
|
||
|
/**************************** Type Definitions *******************************/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
u32 ButtonMask; /* The bit corresponding to the button */
|
||
|
u32 LedMask; /* The bit corresponding to the LED */
|
||
|
} MapButtonTable;
|
||
|
|
||
|
/***************** Macros (Inline Functions) Definitions *********************/
|
||
|
|
||
|
|
||
|
/************************** Function Prototypes ******************************/
|
||
|
|
||
|
int MapButton2Led(u32 Buttons, u32 *ButtonFoundPtr);
|
||
|
|
||
|
void SequenceLeds();
|
||
|
|
||
|
void GpioIsr(void *InstancePtr);
|
||
|
|
||
|
int SetupInterruptSystem();
|
||
|
|
||
|
/************************** Variable Definitions *****************************/
|
||
|
|
||
|
/*
|
||
|
* The following are declared globally so they are zeroed and so they are
|
||
|
* easily accessible from a debugger
|
||
|
*/
|
||
|
static XGpio Gpio; /* The Instance of the GPIO Driver */
|
||
|
|
||
|
static INTC Intc; /* The Instance of the Interrupt Controller Driver */
|
||
|
|
||
|
volatile int InterruptCount; /* Count of interrupts that have occured */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* The following table contains the masks for the buttons and LEDS
|
||
|
* that are connected on the board. It's purpose is to map a button
|
||
|
* to a specific LED.
|
||
|
*/
|
||
|
MapButtonTable Button2LedTable[] =
|
||
|
{ { 0x1, 0x1 },
|
||
|
{ 0x2, 0x2 },
|
||
|
{ 0x4, 0x4 },
|
||
|
{ 0x8, 0x8 },
|
||
|
{ 0x10, 0x8 },
|
||
|
{ 0x20, 0x8 },
|
||
|
{ 0x40, 0x8 },
|
||
|
{ 0x100, 0x10 },
|
||
|
{ 0x200, 0x20 },
|
||
|
{ 0x400, 0x40 },
|
||
|
{ 0x800, 0x80 },
|
||
|
{ 0x1000, 0x80 },
|
||
|
{ 0x2000, 0x80 },
|
||
|
{ 0x4000, 0x80 } };
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
* This function is the main function of the GPIO example. It is responsible
|
||
|
* for initializing the GPIO device, setting up interrupts and providing a
|
||
|
* foreground loop such that interrupt can occur in the background.
|
||
|
*
|
||
|
* @param None.
|
||
|
*
|
||
|
* @return
|
||
|
* - XST_SUCCESS to indicate success.
|
||
|
* - XST_FAILURE to indicate Failure.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
int main(void)
|
||
|
{
|
||
|
int Status;
|
||
|
|
||
|
/* Initialize the GPIO driver. If an error occurs then exit */
|
||
|
|
||
|
Status = XGpio_Initialize(&Gpio, GPIO_DEVICE_ID);
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Perform a self-test on the GPIO. This is a minimal test and only
|
||
|
* verifies that there is not any bus error when reading the data
|
||
|
* register
|
||
|
*/
|
||
|
XGpio_SelfTest(&Gpio);
|
||
|
|
||
|
/*
|
||
|
* Setup direction register so the switch is an input and the LED is
|
||
|
* an output of the GPIO
|
||
|
*/
|
||
|
XGpio_SetDataDirection(&Gpio, BUTTON_CHANNEL, GPIO_ALL_BUTTONS);
|
||
|
XGpio_SetDataDirection(&Gpio, LED_CHANNEL, ~GPIO_ALL_LEDS);
|
||
|
|
||
|
/* Sequence the LEDs to show this example is starting to run */
|
||
|
|
||
|
SequenceLeds();
|
||
|
|
||
|
/*
|
||
|
* Setup the interrupts such that interrupt processing can occur. If
|
||
|
* an error occurs then exit
|
||
|
*/
|
||
|
Status = SetupInterruptSystem();
|
||
|
if (Status != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Loop forever while the button changes are handled by the interrupt
|
||
|
* level processing
|
||
|
*/
|
||
|
while (1) {
|
||
|
}
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
* This function sequences the LEDs by turning them all on, the turning each
|
||
|
* one on individually, then turning them all on, and finally off.
|
||
|
*
|
||
|
* @param None.
|
||
|
*
|
||
|
* @return None.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
void SequenceLeds()
|
||
|
{
|
||
|
u32 Mask = 0x8000;
|
||
|
int Led;
|
||
|
volatile int Delay;
|
||
|
|
||
|
/* Turn on all the LEDS to show starting the sequence */
|
||
|
|
||
|
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, GPIO_ALL_LEDS);
|
||
|
for (Delay = 0; Delay < LED_DELAY; Delay++);
|
||
|
|
||
|
/* Sequence thru turning each LED on one at a time */
|
||
|
|
||
|
for (Led = 1; Led <= 16; Led++) {
|
||
|
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, Mask);
|
||
|
Mask >>= 1;
|
||
|
|
||
|
/* Wait a small amount of time so the LED is visible */
|
||
|
|
||
|
for (Delay = 0; Delay < LED_DELAY; Delay++);
|
||
|
}
|
||
|
|
||
|
/* Turn on all LEDS to show stopping the sequence */
|
||
|
|
||
|
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, GPIO_ALL_LEDS);
|
||
|
for (Delay = 0; Delay < LED_DELAY; Delay++);
|
||
|
|
||
|
/* Turn off all the LEDs */
|
||
|
|
||
|
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0);
|
||
|
|
||
|
XGpio_InterruptClear(&Gpio, XGPIO_IR_MASK);
|
||
|
}
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
* This function maps each button on the board to an LED.
|
||
|
*
|
||
|
* @param Buttons contains the buttons that have changed.
|
||
|
* @param ButtonFoundPtr is a pointer to allow this function to indicate
|
||
|
* the button that was associated with the returned LED. This
|
||
|
* input is needed to allow muliple buttons to change
|
||
|
* simulataneously.
|
||
|
*
|
||
|
* @return
|
||
|
*
|
||
|
* The Led that is associated with the first button that was found to be
|
||
|
* changed. A value of zero indicates no LED was found.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
int MapButton2Led(u32 Buttons, u32 *ButtonFoundPtr)
|
||
|
{
|
||
|
int Index;
|
||
|
|
||
|
/* Look thru the table to map the button to an LED */
|
||
|
|
||
|
for (Index = 0; Index < sizeof(Button2LedTable)/ sizeof(MapButtonTable);
|
||
|
Index++) {
|
||
|
|
||
|
/*
|
||
|
* Determine which LED corresponds to the button being careful
|
||
|
* because more than one button could have changed
|
||
|
*/
|
||
|
if (Button2LedTable[Index].ButtonMask ==
|
||
|
(Buttons & Button2LedTable[Index].ButtonMask)) {
|
||
|
/*
|
||
|
* If the button was found then return the
|
||
|
* associated LED
|
||
|
*/
|
||
|
*ButtonFoundPtr = Button2LedTable[Index].ButtonMask;
|
||
|
return Button2LedTable[Index].LedMask;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If no button was found in the table, then indicate no LED */
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
* This function is the Interrupt Service Routine for the GPIO device. It
|
||
|
* will be called by the processor whenever an interrupt is asserted by the
|
||
|
* device.
|
||
|
*
|
||
|
* This function will detect the push button on the board has changed state
|
||
|
* and then turn on or off the LED.
|
||
|
*
|
||
|
* @param InstancePtr is the GPIO instance pointer to operate on.
|
||
|
* It is a void pointer to meet the interface of an interrupt
|
||
|
* processing function.
|
||
|
*
|
||
|
* @return None.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
void GpioIsr(void *InstancePtr)
|
||
|
{
|
||
|
XGpio *GpioPtr = (XGpio *)InstancePtr;
|
||
|
u32 Led;
|
||
|
u32 LedState;
|
||
|
u32 Buttons;
|
||
|
u32 ButtonFound;
|
||
|
u32 ButtonsChanged = 0;
|
||
|
static u32 PreviousButtons;
|
||
|
|
||
|
/*
|
||
|
* Disable the interrupt
|
||
|
*/
|
||
|
XGpio_InterruptDisable(GpioPtr, BUTTON_INTERRUPT);
|
||
|
|
||
|
/* Keep track of the number of interrupts that occur */
|
||
|
|
||
|
InterruptCount++;
|
||
|
|
||
|
/*
|
||
|
* There should not be any other interrupts occuring other than the
|
||
|
* the button changes
|
||
|
*/
|
||
|
if ((XGpio_InterruptGetStatus(GpioPtr) & BUTTON_INTERRUPT) !=
|
||
|
BUTTON_INTERRUPT) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Read state of push buttons and determine which ones changed
|
||
|
* states from the previous interrupt. Save a copy of the buttons
|
||
|
* for the next interrupt
|
||
|
*/
|
||
|
Buttons = XGpio_DiscreteRead(GpioPtr, BUTTON_CHANNEL);
|
||
|
ButtonsChanged = Buttons ^ PreviousButtons;
|
||
|
PreviousButtons = Buttons;
|
||
|
|
||
|
/*
|
||
|
* Handle all button state changes that occurred since the last
|
||
|
* interrupt
|
||
|
*/
|
||
|
while (ButtonsChanged != 0) {
|
||
|
/*
|
||
|
* Determine which button changed state and then get
|
||
|
* the current state of the associated LED
|
||
|
*/
|
||
|
Led = MapButton2Led(ButtonsChanged, &ButtonFound);
|
||
|
LedState = XGpio_DiscreteRead(GpioPtr, LED_CHANNEL) & Led;
|
||
|
|
||
|
/*
|
||
|
* Clear the button that is being processed so that it is
|
||
|
* done and others can be handled also
|
||
|
*/
|
||
|
ButtonsChanged &= ~ButtonFound;
|
||
|
|
||
|
/* Toggle the state of the LED */
|
||
|
if (LedState) {
|
||
|
XGpio_DiscreteClear(GpioPtr, LED_CHANNEL, Led);
|
||
|
} else {
|
||
|
XGpio_DiscreteSet(GpioPtr, LED_CHANNEL, Led);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Clear the interrupt such that it is no longer pending in the GPIO */
|
||
|
|
||
|
(void)XGpio_InterruptClear(GpioPtr, BUTTON_INTERRUPT);
|
||
|
|
||
|
/*
|
||
|
* Enable the interrupt
|
||
|
*/
|
||
|
XGpio_InterruptEnable(GpioPtr, BUTTON_INTERRUPT);
|
||
|
|
||
|
}
|
||
|
|
||
|
/****************************************************************************/
|
||
|
/**
|
||
|
* This function sets up the interrupt system for the example. The processing
|
||
|
* contained in this funtion assumes the hardware system was built with
|
||
|
* and interrupt controller.
|
||
|
*
|
||
|
* @param None.
|
||
|
*
|
||
|
* @return A status indicating XST_SUCCESS or a value that is contained in
|
||
|
* xstatus.h.
|
||
|
*
|
||
|
* @note None.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
int SetupInterruptSystem()
|
||
|
{
|
||
|
int Result;
|
||
|
INTC *IntcInstancePtr = &Intc;
|
||
|
|
||
|
#ifdef XPAR_INTC_0_DEVICE_ID
|
||
|
/*
|
||
|
* Initialize the interrupt controller driver so that it's ready to use.
|
||
|
* specify the device ID that was generated in xparameters.h
|
||
|
*/
|
||
|
Result = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
|
||
|
if (Result != XST_SUCCESS) {
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
/* Hook up interrupt service routine */
|
||
|
XIntc_Connect(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
|
||
|
(Xil_ExceptionHandler)GpioIsr, &Gpio);
|
||
|
|
||
|
/* Enable the interrupt vector at the interrupt controller */
|
||
|
|
||
|
XIntc_Enable(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID);
|
||
|
|
||
|
/*
|
||
|
* Start the interrupt controller such that interrupts are recognized
|
||
|
* and handled by the processor
|
||
|
*/
|
||
|
Result = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
|
||
|
if (Result != XST_SUCCESS) {
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|
||
|
Result = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
|
||
|
IntcConfig->CpuBaseAddress);
|
||
|
if (Result != XST_SUCCESS) {
|
||
|
return XST_FAILURE;
|
||
|
}
|
||
|
|
||
|
XScuGic_SetPriorityTriggerType(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
|
||
|
0xA0, 0x3);
|
||
|
|
||
|
/*
|
||
|
* Connect the interrupt handler that will be called when an
|
||
|
* interrupt occurs for the device.
|
||
|
*/
|
||
|
Result = XScuGic_Connect(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
|
||
|
(Xil_ExceptionHandler)GpioIsr, &Gpio);
|
||
|
if (Result != XST_SUCCESS) {
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Enable the interrupt for the GPIO device.
|
||
|
*/
|
||
|
XScuGic_Enable(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Enable the GPIO channel interrupts so that push button can be
|
||
|
* detected and enable interrupts for the GPIO device
|
||
|
*/
|
||
|
XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
|
||
|
XGpio_InterruptGlobalEnable(&Gpio);
|
||
|
|
||
|
/*
|
||
|
* Initialize the exception table and register the interrupt
|
||
|
* controller handler with the exception table
|
||
|
*/
|
||
|
Xil_ExceptionInit();
|
||
|
|
||
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||
|
(Xil_ExceptionHandler)INTC_HANDLER, IntcInstancePtr);
|
||
|
|
||
|
/* Enable non-critical exceptions */
|
||
|
Xil_ExceptionEnable();
|
||
|
|
||
|
return XST_SUCCESS;
|
||
|
}
|