/***************************** Include Files *********************************/
#include "xparameters.h" #include "xgpio.h" #include "xil_exception.h"
#ifdef XPAR_INTC_0_DEVICE_ID #include "xintc.h" #include #else #include "xscugic.h" #include "xil_printf.h" #endif
/************************** 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 GPIO_DEVICE_ID XPAR_GPIO_0_DEVICE_ID #define GPIO_CHANNEL1 1
#ifdef XPAR_INTC_0_DEVICE_ID #define INTC_GPIO_INTERRUPT_ID XPAR_INTC_0_GPIO_0_VEC_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #else #define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_1_IP2INTC_IRPT_INTR #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID #endif /* XPAR_INTC_0_DEVICE_ID */
/* * 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 determines which buttons must be pressed at the same * time to cause interrupt processing to stop and start */ #define INTERRUPT_CONTROL_VALUE 0x7
/* * 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
#endif /* TESTAPP_GEN */
#define INTR_DELAY 0x00FFFFFF
#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 /* XPAR_INTC_0_DEVICE_ID */
/************************** Function Prototypes ******************************/ void GpioHandler(void *CallBackRef);
int GpioIntrExample(INTC *IntcInstancePtr, XGpio *InstancePtr, u16 DeviceId, u16 IntrId, u16 IntrMask, u32 *DataRead);
int GpioSetupIntrSystem(INTC *IntcInstancePtr, XGpio *InstancePtr, u16 DeviceId, u16 IntrId, u16 IntrMask);
void GpioDisableIntr(INTC *IntcInstancePtr, XGpio *InstancePtr, u16 IntrId, u16 IntrMask);
/************************** Variable Definitions *****************************/
/* * The following are declared globally so they are zeroed and so they are * easily accessible from a debugger */ XGpio Gpio; /* The Instance of the GPIO Driver */
INTC Intc; /* The Instance of the Interrupt Controller Driver */
static u16 GlobalIntrMask; /* GPIO channel mask that is needed by * the Interrupt Handler */
static volatile u32 IntrFlag; /* Interrupt Handler Flag */
/****************************************************************************/ /** * 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. * *****************************************************************************/ #ifndef TESTAPP_GEN int main(void) { int Status; u32 DataRead;
print(" Press button to Generate Interrupt\r\n");
Status = GpioIntrExample(&Intc, &Gpio, GPIO_DEVICE_ID, INTC_GPIO_INTERRUPT_ID, GPIO_CHANNEL1, &DataRead);
if (Status == 0 ){ if(DataRead == 0) print("No button pressed. \r\n"); else print("Gpio Interrupt Test PASSED. \r\n"); } else { print("Gpio Interrupt Test FAILED.\r\n"); return XST_FAILURE; }
return XST_SUCCESS; } #endif
/******************************************************************************/ /** * * This is the entry function from the TestAppGen tool generated application * which tests the interrupts when enabled in the GPIO * * @param IntcInstancePtr is a reference to the Interrupt Controller * driver Instance * @param InstancePtr is a reference to the GPIO driver Instance * @param DeviceId is the XPAR__DEVICE_ID value from * xparameters.h * @param IntrId is XPAR___IP2INTC_IRPT_INTR * value from xparameters.h * @param IntrMask is the GPIO channel mask * @param DataRead is the pointer where the data read from GPIO Input is * returned * * @return * - XST_SUCCESS if the Test is successful * - XST_FAILURE if the test is not successful * * @note None. * ******************************************************************************/ int GpioIntrExample(INTC *IntcInstancePtr, XGpio* InstancePtr, u16 DeviceId, u16 IntrId, u16 IntrMask, u32 *DataRead) { int Status; u32 delay;
/* Initialize the GPIO driver. If an error occurs then exit */ Status = XGpio_Initialize(InstancePtr, DeviceId); if (Status != XST_SUCCESS) { return XST_FAILURE; }
Status = GpioSetupIntrSystem(IntcInstancePtr, InstancePtr, DeviceId, IntrId, IntrMask); if (Status != XST_SUCCESS) { return XST_FAILURE; }
IntrFlag = 0; delay = 0;
while(!IntrFlag && (delay < INTR_DELAY)) { delay++; }
GpioDisableIntr(IntcInstancePtr, InstancePtr, IntrId, IntrMask);
*DataRead = IntrFlag;
return Status; }
/******************************************************************************/ /** * * This function performs the GPIO set up for Interrupts * * @param IntcInstancePtr is a reference to the Interrupt Controller * driver Instance * @param InstancePtr is a reference to the GPIO driver Instance * @param DeviceId is the XPAR__DEVICE_ID value from * xparameters.h * @param IntrId is XPAR___IP2INTC_IRPT_INTR * value from xparameters.h * @param IntrMask is the GPIO channel mask * * @return XST_SUCCESS if the Test is successful, otherwise XST_FAILURE * * @note None. * ******************************************************************************/ int GpioSetupIntrSystem(INTC *IntcInstancePtr, XGpio *InstancePtr, u16 DeviceId, u16 IntrId, u16 IntrMask) { int Result;
GlobalIntrMask = IntrMask;
#ifdef XPAR_INTC_0_DEVICE_ID
#ifndef TESTAPP_GEN /* * 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; } #endif /* TESTAPP_GEN */
/* Hook up interrupt service routine */ XIntc_Connect(IntcInstancePtr, IntrId, (Xil_ExceptionHandler)GpioHandler, InstancePtr);
/* Enable the interrupt vector at the interrupt controller */ XIntc_Enable(IntcInstancePtr, IntrId);
#ifndef TESTAPP_GEN /* * 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; } #endif /* TESTAPP_GEN */
#else /* !XPAR_INTC_0_DEVICE_ID */
#ifndef TESTAPP_GEN 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; } #endif /* TESTAPP_GEN */
XScuGic_SetPriorityTriggerType(IntcInstancePtr, IntrId, 0xA0, 0x3);
/* * Connect the interrupt handler that will be called when an * interrupt occurs for the device. */ Result = XScuGic_Connect(IntcInstancePtr, IntrId, (Xil_ExceptionHandler)GpioHandler, InstancePtr); if (Result != XST_SUCCESS) { return Result; }
/* Enable the interrupt for the GPIO device.*/ XScuGic_Enable(IntcInstancePtr, IntrId); #endif /* XPAR_INTC_0_DEVICE_ID */
/* * Enable the GPIO channel interrupts so that push button can be * detected and enable interrupts for the GPIO device */ XGpio_InterruptEnable(InstancePtr, IntrMask); XGpio_InterruptGlobalEnable(InstancePtr);
/* * 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; }
/******************************************************************************/ /** * * This is the interrupt handler routine for the GPIO for this example. * * @param CallbackRef is the Callback reference for the handler. * * @return None. * * @note None. * ******************************************************************************/ void GpioHandler(void *CallbackRef) { XGpio *GpioPtr = (XGpio *)CallbackRef;
IntrFlag = 1;
/* Clear the Interrupt */ XGpio_InterruptClear(GpioPtr, GlobalIntrMask);
}
/******************************************************************************/ /** * * This function disables the interrupts for the GPIO * * @param IntcInstancePtr is a pointer to the Interrupt Controller * driver Instance * @param InstancePtr is a pointer to the GPIO driver Instance * @param IntrId is XPAR___VEC * value from xparameters.h * @param IntrMask is the GPIO channel mask * * @return None * * @note None. * ******************************************************************************/ void GpioDisableIntr(INTC *IntcInstancePtr, XGpio *InstancePtr, u16 IntrId, u16 IntrMask) { XGpio_InterruptDisable(InstancePtr, IntrMask); #ifdef XPAR_INTC_0_DEVICE_ID XIntc_Disable(IntcInstancePtr, IntrId); #else /* Disconnect the interrupt */ XScuGic_Disable(IntcInstancePtr, IntrId); XScuGic_Disconnect(IntcInstancePtr, IntrId); #endif return; } |