Configuring GPIO Interrupts

From Texas Instruments Wiki
Jump to: navigation, search

Introduction

Most TI devices with a 64x+ or 674x processor core use the same GPIO module.
Device Level Diagram of GPIO Hookup (DM355)
Diagram of GPIO Bank Interrupts (DM355)

Devices with this module (as of October 11, 2010):

  • DM355
  • DM365
  • DM644x
  • DM646x
  • C642x
  • DM643x
  • C674x
  • OMAP-L13x
  • C645x
  • C647x

This article is intended to give detailed instructions on how to setup interrupts when using this GPIO module.

Device Level Configuration

Pin muxing

  • Make sure that pins you want configured as GPIO are configured in the device-wide pin-muxing registers to be GPIO function and not some other peripheral function.
  • For example, in C6424 this would be done in the registers PINMUX0 and PINMUX1 as described in the C6424 datasheet.

Power, Reset, Clock

  • These devices have a module called the Power and Sleep Controller (PSC) that controls power, reset, and clock to all the peripherals. Make sure the peripheral is powered and in an "enabled" state, i.e. peripheral clock enabled and peripheral out of reset.
  • Generally the gel file corresponding to a given device will turn on all peripheral domains when you connect to the device with the emulator. When transitioning from development to production this duty would shift from the gel file to the bootloader.

GPIO Configuration

  1. Configure the GPIO pin as an input by writing 1 to its respective bit in the DIRxy register.
  2. Enable a rising edge and/or falling edge interrupt by writing to the appropriate bit in the SET_RIS_TRIGxy/SET_FAL_TRIGxy register.
  3. Enable the bank interrupt for the corresponding interrupt by writing to BINTEN.ENn where n is the bank number. Note: This step must be performed regardless of whether you're planning to ultimately use a "direct" interrupt or the "bank" interrupt. The ENn bit gates all interrupts from the GPIO module.

Interrupt Controller Configuration

Since a number of devices use this peripheral there are multiple interrupt controllers that are used in conjunction. This includes the ARM Interrupt Controller (AINTC) and the GEM Interrupt Controller. The AINTC is generally documented in the ARM Subsystem Reference Guide for the processor family being used. For example, here is the DM644x ARM Subsystem Reference Guide which would be applicable for DM6446, DM6443, and DM6441. For 64x+ devices you would find the corresponding documentation in the Interrupt Controller chapter of the 64x+ Megamodule Reference Guide and the Interrupts chapter of the 64x+ CPU and Instruction Set Reference Guide. BIOS users should see Setting up interrupts in DSP BIOS.

Generally speaking you would need to perform the following steps:

  1. Plug your ISR into the interrupt vector table.
  2. Map the desired interrupt (direct or bank) to one of the CPU interrupts, e.g. IRQ/FIQ on ARM or one of the 12 maskable interrupts for DSP.
  3. Enable the corresponding interrupt using EINT[n] on the ARM or IER[n] on the DSP. Note: Some devices have a bank of interrupts that has both direct interrupts and a bank interrupt. You should either use direct interrupts only or the bank interrupt. Using both types of interrupts for a given bank can lead to double interrupts. For more info on this scenario please read the article Avoiding Double Interrupts with the GPIO Peripheral.
  4. Globally enable interrupts.

GPIO ISR

  1. Interrupt acknowledgment
    • 64x+: If using one of the 12 CPU interrupts you do not need to do any kind of acknowledgment. The corresponding IFR bit is automatically cleared by the hardware upon acceptance of the interrupt. If using the Event Combiner you would need to clear the corresponding event through the EVTCLRx register.
    • AINTC: The interrupt needs to be acknowledged by writing 1 to the corresponding IRQ[n]/FIQ[n] bit.
  2. INTSTAT acknowledgement
    • If for a given bank of 16 GPIOs you are using only direct interrupts then you need not touch INTSTAT as it is not in the "path" of the interrupt.
    • When using a bank interrupt you should read the INTSTAT register to see which GPIO interrupts have occurred. Upon servicing that interrupt you must clear the corresponding INTSTAT bit by writing a 1 to it. Writing a 1 to an INTSTAT bit clears it. Writing a 0 has no effect.

Example Project

An example project that runs on C6424 EVM or DM648 EVM can be downloaded here:

GPIO_interrupts.zip

The example was created using CCS 4.0 and BIOS 5.40, though it could be easily adapted to run with CCS 3.3 and BIOS 5.33 (just create a new project and add the files).

The directions for building the project are in the comments at the top of main.c. One tip -- make sure you choose the proper build configuration (C6424 or DM648) based on the hardware you're using!