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 (92,738 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

 

 

 

Comments
by Newbie david.bashford
on ‎02-05-2014 03:30 PM

The helloworld attachment is corrupted.  Truncated actually.

 

It'd also be nice to see simpler or more modular examples.  For the MicroZed board, for instance, why not a simple example that triggers an interrupt when the button is pushed?

by Xilinx Employee
on ‎02-05-2014 04:07 PM

David,

 

I just downloaded and successfully opened the helloworld file. One possible problem: it's a Microsoft Word doc not a text doc. That's an unfortunate limitation of the blogging platform.

 

--Steve

 

by Observer taylo_ap
on ‎02-07-2014 01:07 AM - last edited on ‎02-07-2014 09:47 AM by Xilinx Employee

Hi David,

 

Thanks for the feedback (and for reading it in the first place Smiley Wink )

 

This blog does do that i.e. when the button is pushed you get an interupt and a print out over STDOUT. I had left the XADC data in there and running to demonstrate the nature of the interrupt, for want of a better word interrupting that process.

 

The more recent blogs however as I look at the Watchdogs, and TTC are more stand modular in there code examples I hope.

 

Thanks again

 

Adam

by Newbie jonathanhome
on ‎03-16-2014 09:42 AM

Hi Adam,

 

I have been following the blog and would like to try out your helloworld example. Could you re-port the file such that I can see how you function;

static void IntrHandler(void *CallBackRef, int Bank, u32 Status)

looks like? Would like to give it a try.

 

Also I find your blog very useful, thank you for the effort.

 

regards

Ludwig

 

 

by Observer taylo_ap
on ‎03-17-2014 01:38 PM

Hi Ludwig,

 

It is corruption of the file i supplied to Steve, I have sent along a new one which is uncorrupted hopefully it will be re-posted very soon.

 

Thanks for reading the series 

 

Adam 

by Xilinx Employee
on ‎03-17-2014 01:57 PM

Thanks everyone. I have posted the new Word file.

 

--Steve

 

by Visitor osamaamin
on ‎09-10-2014 07:01 AM

Hi,

 

Thanks for the excellent article.

 

Can you please guide me how can i write a linux application running on zynq that does exactly the same as your code, without changing the device tree file or recompiling the kernel?

 

thank you so much

 

 

by Observer taylo_ap
on ‎09-11-2014 12:55 AM

osamaamin

 

I will be looking at how we use linux and running a similar set of example over the next few months, thanks for the kind comments on the blog please spread the word about it 

 

Adam 

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.