UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

More About MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 13

by Xilinx Employee ‎01-03-2014 10:41 AM - edited ‎05-26-2015 04:32 PM (327,757 Views)

By Adam Taylor

 

Having looked at interrupts and the different interrupt types available on the Zynq All Programmable SoC in my previous post (MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 12), this blog post focuses on using a Shared Peripheral Interrupt GPIO interrupt.

 

To implement this interrupt structure correctly, we will need to write two functions:

 

 

  • Interrupt service routine (ISR) – defines the actions that occur when the interrupt occurs.
  • Interrupt Set Up – Configures the interrupts. This routine sets up and enables a GPIO interrupt. It will be generic for all interrupts within the system to aid code reuse.

 

 

Thankfully the standalone board support package (BSP) contains a number of functions that greatly ease this task. You’ll find these functions within the following header files:

 

 

  • Xparameters.h – defines processor device IDs
  • XGPIOS.h – drivers for GPIO configuration and use
  • Xscugic.h – drivers for GIC (General Interrupt Controller) configuration and use
  • Xil_exception.h – exception functions for the ARM Cortex-A9 processor

 

 

Just as before, when we wrote code to communicate with the Zynq SoC’s XADC (MicroZed XADC Software: Adam Taylor’s MicroZed Chronicles Part 8), we need to know the hardware ID parameters for the on-chip devices we wish to use. For this example, those devices are the GIC and GPIO. These parameters are provided mostly within the BSP header file xparameters.h with the exception of the interrupt ID, which is provided by xparameters_ps.h. There is no need to declare this header file within your source code; it is included by the xparameters.h file.

 

 

#define GPIO_DEVICE_ID             XPAR_XGPIOPS_0_DEVICE_ID

#define INTC_DEVICE_ID             XPAR_SCUGIC_SINGLE_DEVICE_ID

#define GPIO_INTERRUPT_ID    XPS_GPIO_INT_ID

 

To set up the interrupt, we need two static global variables and the interrupt ID defined above

 

static XScuGic Intc;        // Interrupt Controller Driver

static XGpioPs Gpio;     //GPIO Device

 

To set up the interrupts, we initialize the exceptions, configure and initialize the GIC, and then connect the GIC to the interrupt handling hardware. The functions needed to do this are provided within the Xil_exception.h and Xscugic.h files.

 

When it comes to configuring the GPIO to function as an interrupt source, we can configure either an entire I/O bank or an individual pin using functions provided within xgpiops.h. For example:

 

 

void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask);

 

void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, int Pin);

 

 

We also need to configure the interrupt correctly: edge triggered or level triggered and which edge or level? We configure the interrupt using this function:

 

 

void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, int Pin, u8 IrqType);

 

 

Where the IrqType is defined by one of the five definitions within the xgpiops.h file:

 

 

#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0      /**< Interrupt on Rising edge */

#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 1   /**< Interrupt Falling edge */

#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 2        /**< Interrupt on both edges */

#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 3        /**< Interrupt on high level */

#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 4         /**< Interrupt on low level */

 

Note that we can configure edge-triggered interrupts to be either rising- or falling-edge interrupts or we can have the interrupt trigger on both rising and falling edges.

 

If you decide to enable an entire I/O bank, you’ll need to know which bank is associated with the pin or pins you wish to use for interrupts. The Zynq SoC supports a maximum of 118 GPIO pins. For the configuration in this example, all of the MIO (54 pins) are being used as GPIO along with the EMIO (64 pins), broken into four banks with each bank containing 32 pins.

 

The interrupt set-up function will also define the ISR, which will be called when an interrupt occurs. We use this function:

 

 

XGpioPs_SetCallbackHandler(Gpio, (void *)Gpio, IntrHandler);

 

 

Having written the interrupt set-up code, our next step will be to write the actual ISR that will be called when an interrupt occurs. An ISR can be as simple or as complicated as the application requires. For this example, the ISR will perform the same task as in the previous polled I/O example: it will toggle the status of the led on and off each time the button is pressed. The ISR will also print out to the console a message when it is run.

 

Note: Code for a suitably modified version of helloworld.c that uses interrupts is attached to this blog. The original helloworld.c code using polled I/O appeared in: MicroZed XADC Software: Adam Taylor’s MicroZed Chronicles Part 8

 

 

 

Please see the previous entries in this MicroZed series by Adam Taylor:

 

MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 12

 

Using the MicroZed Button for Input: Adam Taylor’s MicroZed Chronicles Part 11

 

Driving the Zynq SoC's GPIO: Adam Taylor’s MicroZed Chronicles Part 10

 

Meet the Zynq MIO: Adam Taylor’s MicroZed Chronicles Part 9

 

MicroZed XADC Software: Adam Taylor’s MicroZed Chronicles Part 8

 

Getting the XADC Running on the MicroZed: Adam Taylor’s MicroZed Chronicles Part 7

 

A Boot Loader for MicroZed. Adam Taylor’s MicroZed Chronicles, Part 6 

 

Figuring out the MicroZed Boot Loader – Adam Taylor’s MicroZed Chronicles, Part 5

 

Running your programs on the MicroZed – Adam Taylor’s MicroZed Chronicles, Part 4

 

Zynq and MicroZed say “Hello World”-- Adam Taylor’s MicroZed Chronicles, Part 3

 

Adam Taylor’s MicroZed Chronicles: Setting the SW Scene

 

Bringing up the Avnet MicroZed with Vivado

 

 

 

Labels
About the Author
  • Be sure to join the Xilinx LinkedIn group to get an update for every new Xcell Daily post! ******************** Steve Leibson is the Director of Strategic Marketing and Business Planning at Xilinx. He started as a system design engineer at HP in the early days of desktop computing, then switched to EDA at Cadnetix, and subsequently became a technical editor for EDN Magazine. He's served as Editor in Chief of EDN Magazine, Embedded Developers Journal, and Microprocessor Report. He has extensive experience in computing, microprocessors, microcontrollers, embedded systems design, design IP, EDA, and programmable logic.