Embedded Freaks..

August 14, 2009

Cortex-M3 Interrupt/Exception Control

Filed under: Cortex-M — Tags: — kunilkuda @ 9:18 pm

Cortex-M3 has NVIC (Nested Vector Interrupt Controller), a kind of peripheral, to support up to 255 interrupts.

Other than that, it also has WIC (Wakeup Interrupt Controller), which similar to NVIC, but it doesn’t need any clock to run. Hence it can be used to detect any interrupt during sleep mode without burning energy (no need to have any clock running on system at all).

Since WIC is only available on rev2 Cortex-M3 (currently only LPC17xx that have it), this post will only discuss the NVIC control.

Configurable Priority vs Unconfigurable Priority Interrupt

On Cortex-M3, the exceptions / interrupts are divided into two categories, based on their priority: configurable and unconfigurable. The unconfigurable priority interrupts have fixed priority, and consist of 3 interrupts:

  1. Reset. Invoked on power on and reset
  2. Non Maskable Interrupt. An external interrupt (activated by external pin) that is unstoppable except by reset.
  3. Hard fault. Any fault that is not handled by other fault handlers (memory management fault, bus fault, usage fault) will activate this interrupt. The interrupt is also activated when the other fault handlers are turned off

Those interrupts / exceptions are the basic interrupts that are expected to be handled by the application (read: MUST be implemented by application). The priority is started at -3 for Reset, -2 for NMI, and -1 for Hard fault.

The rest of 252 interrupts are priority configurable, starting at 0 (the highest priority) until 252 (the lowest priority).

Global Interrupt Enable / Disable

During the initial reset, NVIC is turned off. Therefore, the processor cannot receive any interrupts (except for NMI, Reset interrupt, and hard fault). To turn on the interrupts with configurable priority:

asm volatile ("cpsie i");

“CPSIE I” is a assembly instruction to enable the priority configurable interrupts. Actually, it’s a shortcut to this longer procedure

asm volatile ("MOVS r0, #0\n\
MSR PRIMASK, r0");

To turn off the priority configurable interrupts:

asm volatile ("cpsid i");

Or, taking the longer non-atomic procedure:

asm volatile ("MOVS r0, #1\n\
MSR PRIMASK, r0");

Actually, if it is needed, the hard fault interrupt can be turned off as well (along with the priority configurable interrupts) with this command:

asm volatile ("cpsid f");

Or, using longer non-atomic procedure

asm volatile ("MOVS r0, #1\n\
MSR FAULTMASK, r0");

To turn on the hard fault interrupt with the other priority configurable interrupts, use:

asm volatile ("cpsie f");

Or, using longer non-atomic procedure

asm volatile ("MOVS r0, #0\n\
MSR FAULTMASK, r0");

Enabling / Disabling Group of Interrupts

Since you have up to 255 interrupts, it’s odd to have just single global interrupt on/off. Hence, ARM created a register to enable/disable group of interrupts, based on their priority, the BASEPRI. If you set the BASEPRI, the interrupts with the same priority level or lower (ie. the priority number is bigger than BASEPRI) will be masked.

Here’s how to set it:

asm volatile ("MOVS r0, #5\n\
MSR BASEPRI, r0");

The above code will mask the interrupts with priority 5 or below. To reset/disable the BASEPRI, just replace #5 with #0.

Enabling / Disabling Specific Interrupts

This one is very easy. If you look at the Cortex-M3 technical manual, the only thing that you need to do is to set IRQ X ‘Set Enable Register’ (ISER) or ‘Clear Enable Register’ (ICER). For example, to turn on TIMER0 interrupts (Match0, Match1, Capture0, Capture1) on LPC1766, you can use:


NVIC->ISER[0] = (1 << 1);

// Or if you have downloaded CMSIS library, you can use:

NVIC_EnableIRQ(TIMER0_IRQn);

The NVIC_EnableIRQ() is in core_cm3.h file at CMSIS library source code. Don’t forget to include “LPC17xx.h” too, before using these functions from core_cm3.h

About these ads

2 Comments »

  1. can i disable all ‘enabled’ interrupts and re-enable them??

    Comment by mshrestha — January 10, 2012 @ 6:38 am

  2. can i disable all ‘enabled’ interrupts and re-enable them??

    Comment by mshrestha — January 10, 2012 @ 6:39 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: