The ARM Cortex Microcontroller has an advanced interrupt controller called the Nested Vectored Interrupt Controller (NVIC) that provides low latency interrupt processing and efficient prioritized interrupts. The NVIC handles all the interrupts for the processor and allows for efficient management of multiple simultaneous interrupt requests.
Overview of NVIC
The NVIC replaces the traditional single level interrupt controller with a multi-level priority based interrupt handling mechanism. This allows higher priority interrupts to interrupt lower priority ones. The NVIC supports up to 240 interrupt inputs and 16 priority levels for efficient prioritization.
The NVIC registers allow you to configure, control and monitor the interrupts and exceptions on the Cortex-M processor. By properly configuring these registers, you can optimize interrupt handling for your application.
NVIC Register Types
There are several types of registers in the NVIC module:
- Interrupt Set Enable Registers – Enable interrupts
- Interrupt Clear Enable Registers – Disable interrupts
- Interrupt Set Pending Registers – Force interrupts into pending state
- Interrupt Clear Pending Registers – Remove pending state from interrupts
- Priority Registers – Set priority level of interrupts
- Vector Table Offset Register – Relocate vector table in memory
- Interrupt Control State Registers – Set/clear interrupts
- System Control Registers – Control power management, special features
By properly configuring these registers, the NVIC can be customized for a specific application’s needs.
Key NVIC Registers
Here are some of the key NVIC registers that are commonly used:
ISER – Interrupt Set Enable Registers
The Interrupt Set-Enable Registers enable interrupts and exceptions. Setting a bit in these registers enables the corresponding interrupt.
ICER – Interrupt Clear Enable Registers
The Interrupt Clear Enable Registers disable interrupts when set. Writing 1 to a bit position disables that particular interrupt.
ISPR – Interrupt Set Pending Registers
The Interrupt Set Pending Registers are used to force interrupts into pending state. Setting a bit causes the corresponding interrupt to pend.
ICPR – Interrupt Clear Pending Registers
The Interrupt Clear Pending Registers remove the pending state of interrupts. Writing 1 clears the pending state for the corresponding interrupt.
IPR – Interrupt Priority Registers
These registers hold the priority level of the various interrupts. There are 8 bits per register allowing 256 priority levels. The lower the value, the higher the priority.
VTOR – Vector Table Offset Register
This register contains the offset address of the vector table. It can be configured to relocate the vector table anywhere in the code memory.
SCR – System Control Register
The System Control Register controls overall functions like sleep modes, exception behavior, FIQ handling etc. Bits like SEVONPEND allow wake from sleep on pending interrupts.
SHPR – System Handler Priority Registers
These registers set the priority levels of the exception handlers. This allows configuring the priority of faults, NMIs and SVCalls.
CCCR – Coprocessor Access Control Register
The CCCR controls access permissions for coprocessors like FPU. Software can enable or disable coprocessor access using this register.
Commonly Used NVIC Functions
Here are some common operations performed using the NVIC registers:
- Enable Interrupt – Set ISER bit for the interrupt number
- Disable Interrupt – Set ICER bit for the interrupt number
- Set Priority – Write priority value to IPR register
- Set Pending State – Set ISPR bit for the interrupt number
- Clear Pending State – Set ICPR bit for the interrupt number
- Relocate Vector Table – Write offset to VTOR register
By properly configuring the NVIC registers in the initialization code, the interrupts can be optimized for the application. The priority registers are used to prioritize the interrupts as per their real-time needs.
NVIC Register Programming
Here is an example code snippet to demonstrate NVIC register programming: // Enable Interrupt NVIC->ISER = (1 << IRQ_NUMBER); // Set Priority – Lower value is higher priority NVIC->IPR[IRQ_NUMBER] = 0x40; // Set Interrupt Pending NVIC->ISPR = (1 << IRQ_NUMBER); // Relocate Vector Table NVIC->VTOR = NEW_VECTOR_TABLE_OFFSET;
The NVIC registers can be accessed by dereferencing the NVIC peripheral pointer. Each ISER, ICER, ISPR, ICPR register handles 32 interrupts. By setting the right bit in the right register, any interrupt can be configured.
The IPR registers are used to assign priority levels to interrupts. VTOR relocates the vector table anywhere in code memory. Thus NVIC provides complete flexibility in interrupt handling.
Use of NVIC Registers in Application
Some typical usage scenarios for NVIC registers are:
- Set up interrupt priorities in the initialization code using IPR
- Enable required interrupts for peripherals using ISER
- Disable unnecessary interrupts to optimize handling using ICER
- Wake CPU from sleep on external interrupt using SEVONPEND bit in SCR
- Boost priority temporarily for time-critical tasks using IPR
- Configure vectortable location for bootloaders using VTOR
So the NVIC registers are extensively used in the vector table, peripheral driver and OS related code. They help provide full control over interrupt handling priorities and behavior.
The Nested Vectored Interrupt Controller provides a powerful set of registers to manage interrupts in Cortex-M processors. Key registers like ISER, ICER, IPR allow enabling, disabling and prioritizing interrupts. By properly programming the NVIC registers, interrupt latency and performance can be optimized for the application.
So in summary, the NVIC registers are an important tool for configuring interrupts that developers working on ARM Cortex-M need to fully utilize for building robust embedded applications.