How are multiple interrupts sources supposed to be handled. We have developed example code that allows the buttons to generate an interrupt and another where the switches generate an interrupt. When we try to combine the two the button interrupts will still work but the switch interrupt will not. The switches are tied to interrupt level 62 and the buttons are tied to interrupt level 61. Cut and paste appears to have lost all the indentation but code is appended below. Any comments and help are appreciated.
// By commenting or uncommenting out one of next two lines we can get either the switches
// to interrupt on level 62, or the buttons on level 61. When both lines are uncommented
// the button interrupts still work but the switch interrupts do not. How do we get a
// program to handle multiple interrupt levels.
#define USE_SWITCH_INTERRUPT
#define USE_BUTTON_INTERRUPT
/* (Snippets from xparameters.h) included here for information
Definitions for driver GPIO
#define XPAR_XGPIO_NUM_INSTANCES 3
Definitions for peripheral AXI_BUTTONS
#define XPAR_AXI_BUTTONS_BASEADDR 0x41210000
#define XPAR_AXI_BUTTONS_HIGHADDR 0x4121FFFF
#define XPAR_AXI_BUTTONS_DEVICE_ID 0
#define XPAR_AXI_BUTTONS_INTERRUPT_PRESENT 1
#define XPAR_AXI_BUTTONS_IS_DUAL 0
Definitions for peripheral AXI_SWITCHES
#define XPAR_AXI_SWITCHES_BASEADDR 0x41200000
#define XPAR_AXI_SWITCHES_HIGHADDR 0x4120FFFF
#define XPAR_AXI_SWITCHES_DEVICE_ID 1
#define XPAR_AXI_SWITCHES_INTERRUPT_PRESENT 1
#define XPAR_AXI_SWITCHES_IS_DUAL 0
Definitions for peripheral AXI_GPIO_0 (LEDS)
#define XPAR_AXI_GPIO_0_BASEADDR 0x41220000
#define XPAR_AXI_GPIO_0_HIGHADDR 0x4122FFFF
#define XPAR_AXI_GPIO_0_DEVICE_ID 2
#define XPAR_AXI_GPIO_0_INTERRUPT_PRESENT 0
#define XPAR_AXI_GPIO_0_IS_DUAL 0
Definitions for Core_nIRQ/nFIQ interrupts
Definitions for Fabric interrupts connected to ps7_scugic_0
#define XPAR_FABRIC_AXI_BUTTONS_IP2INTC_IRPT_INTR 61
#define XPAR_FABRIC_AXI_SWITCHES_IP2INTC_IRPT_INTR 62
*/
#include "xparameters.h"
#include "xgpio.h"
#include "xil_exception.h"
#include "xscugic.h"
#include <stdio.h>
#include <stdlib.h>
/************************** 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 INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
/************************** Function Prototypes ******************************/
void GpioSwitchesIsr(void *InstancePtr);
void GpioButtonsIsr(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 */
/**
* 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;
print("##### Application Starts #####
r");
#ifdef USE_SWITCH_INTERRUPT
Status = XGpio_Initialize(&Gpio, XPAR_AXI_SWITCHES_DEVICE_ID); //ID=1
print("Switches Initialized
r");
#endif
#ifdef USE_BUTTON_INTERRUPT
Status = XGpio_Initialize(&Gpio, XPAR_AXI_BUTTONS_DEVICE_ID); //ID=0
print("Buttons Initialized
r");
#endif
Status = SetupInterruptSystem();
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
else {
print("Interrupt Systems Initialized
r");
}
/*
* Loop forever while the button changes are handled by the interrupt
* level processing
*/
while (1) {
t /* This section was just to make sure buttons, switches, and leds are
t were working. I could see the button and switch bits working correctly
t when device is toggled.
tunsigned char *buttons;
tunsigned char *switches;
tunsigned char *leds;
tbuttons =(unsigned char *)0x41210000; //Buttons toggled
tswitches=(unsigned char *)0x41200000; //Switches toggled
tleds =(unsigned char *)0x41220000;
tt*leds=*switches;
*/
}
return XST_SUCCESS;
}
/****************************************************************************/
void GpioButtonsIsr(void *InstancePtr)
{
XGpio *GpioPtr = (XGpio *)InstancePtr;
print("entered GPIO ButtonsISR
r");
// Disable the interrupt
XGpio_InterruptDisable(GpioPtr, XGPIO_IR_MASK); //XGPIO_IR_MASK=3
// Clear the interrupt such that it is no longer pending in the GPIO */
(void)XGpio_InterruptClear(GpioPtr, XGPIO_IR_MASK);
print("##### Button Pushed #####
r");
print("r
");
// Re-enable the interrupt
XGpio_InterruptEnable(GpioPtr,XGPIO_IR_MASK);
}
/****************************************************************************/
void GpioSwitchesIsr(void *InstancePtr)
{
XGpio *GpioPtr = (XGpio *)InstancePtr;
print("entered GPIO SwichesISR
r");
// Disable the interrupt
XGpio_InterruptDisable(GpioPtr, XGPIO_IR_MASK); //XGPIO_IR_MASK=3
// Clear the interrupt such that it is no longer pending in the GPIO */
(void)XGpio_InterruptClear(GpioPtr, XGPIO_IR_MASK);
print("##### Switches Pushed #####
r");
print("r
");
// Re-enable the interrupt
XGpio_InterruptEnable(GpioPtr, XGPIO_IR_MASK);
}
/****************************************************************************/
/**
* 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;
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;
}
#ifdef USE_SWITCH_INTERRUPT
//XPAR_FABRIC_AXI_SWITCHES_IP2INTC_IRPT_INTR=62
XScuGic_SetPriorityTriggerType(IntcInstancePtr, XPAR_FABRIC_AXI_SWITCHES_IP2INTC_IRPT_INTR,
0xA0, 0x3);
/*
* Connect the interrupt handler that will be called when an
* interrupt occurs for the device.
*/
Result = XScuGic_Connect(IntcInstancePtr, XPAR_FABRIC_AXI_SWITCHES_IP2INTC_IRPT_INTR,
(Xil_ExceptionHandler)GpioSwitchesIsr, &Gpio);
if (Result != XST_SUCCESS) {
return Result;
}
XScuGic_Enable(IntcInstancePtr, XPAR_FABRIC_AXI_SWITCHES_IP2INTC_IRPT_INTR);
#endif
#ifdef USE_BUTTON_INTERRUPT
//XPAR_FABRIC_AXI_BUTTONS_IP2INTC_IRPT_INTR=61
XScuGic_SetPriorityTriggerType(IntcInstancePtr, XPAR_FABRIC_AXI_BUTTONS_IP2INTC_IRPT_INTR,
0xA0, 0x3);
Result = XScuGic_Connect(IntcInstancePtr, XPAR_FABRIC_AXI_BUTTONS_IP2INTC_IRPT_INTR,
(Xil_ExceptionHandler)GpioButtonsIsr, &Gpio);
if (Result != XST_SUCCESS) {
return Result;
}
XScuGic_Enable(IntcInstancePtr, XPAR_FABRIC_AXI_BUTTONS_IP2INTC_IRPT_INTR);
#endif
/*
* Enable the GPIO channel interrupts so that push button can be
* detected and enable interrupts for the GPIO device
*/
XGpio_InterruptEnable(&Gpio, XGPIO_IR_MASK); // XGPIO_IR_MASK=3
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;
}