The NVIC (Nested Vectored Interrupt Controller) registers ISER, ICER, ISPR and ICPR are used to enable, disable, set pending, and clear pending interrupts in ARM Cortex-M processors. Understanding how to properly configure and use these registers is key to working with interrupts in Cortex-M devices.
What are NVIC Registers?
NVIC stands for Nested Vectored Interrupt Controller. It is the interrupt controller present in ARM Cortex-M series processors used to handle interrupts generated within the device and from external sources. The NVIC unit has a number of control and status registers that are used to configure and control interrupts.
The main registers used for enabling, disabling, setting pending, and clearing pending interrupts are:
- ISER – Interrupt Set Enable Register
- ICER – Interrupt Clear Enable Register
- ISPR – Interrupt Set Pending Register
- ICPR – Interrupt Clear Pending Register
These registers allow interrupts to be individually enabled/disabled and set/cleared pending based on their interrupt number. We’ll take a closer look at how each of these registers work.
ISER – Interrupt Set Enable Register
The Interrupt Set Enable Register (ISER) is used to enable interrupts individually. The ISER is a 32-bit wide register, with each bit corresponding to an interrupt number. Setting a bit in the ISER will enable that particular interrupt. For example: ISER[5] = 1; //enable interrupt #5
Setting a bit in the ISER allows the NVIC to generate an exception when the interrupt triggers. This allows the processor to run the Interrupt Service Routine (ISR) for that interrupt. Multiple interrupts can be enabled by setting multiple bits in the ISER.
It is important to note that enabling an interrupt in the ISER does not actually trigger the interrupt. It only allows the interrupt to be recognized by the NVIC when the interrupt source asserts the correct signal. This avoids spurious interrupts from being continuously generated.
To enable interrupts during chip startup, the ISER register should be configured before enabling exceptions globally using the PRIMASK register. The ISER register maintains its contents even during chip reset, so only newly required interrupts need to be enabled.
ICER – Interrupt Clear Enable Register
The Interrupt Clear Enable Register (ICER) is used to disable interrupts individually. Similar to the ISER, it is a 32-bit register with each bit mapped to an interrupt number. Setting a bit in the ICER will disable that particular interrupt number.
For example: ICER[8] = 1; //disable interrupt #8
Clearing a bit in the ICER prevents that interrupt from being recognized by the NVIC. This can be useful for temporarily disabling interrupts that are not currently required. The NVIC will simply ignore asserts on disabled interrupt lines.
Like the ISER, the ICER maintains its contents across chip reset. Interrupts that need to remain disabled do not need to be reconfigured.
ISPR – Interrupt Set Pending Register
The Interrupt Set Pending Register (ISPR) is used to force interrupts into the pending state. Setting a bit in the ISPR will make the NVIC think that the corresponding interrupt is waiting to be serviced, even if the actual interrupt source has not asserted the interrupt line.
For example: ISPR[7] = 1; //set interrupt #7 as pending
This can be useful to trigger interrupts manually in software, without having to generate the interrupt condition in hardware. If the interrupt is enabled in the ISER, setting it pending in the ISPR will cause the processor to take the exception and run the ISR.
The ISPR is usually used in conjunction with software generated interrupts, or to test interrupt handling code during development. It allows the interrupt handling workflow to be validated before the actual interrupt sources are enabled.
ICPR – Interrupt Clear Pending Register
The Interrupt Clear Pending Register (ICPR) is used to clear pending interrupts. When an interrupt occurs, it gets set to a pending state until the processor services it by running the ISR. The ICPR allows pending interrupts to be cleared manually.
For example: ICPR[9] = 1; //clear pending state of interrupt #9
This allows firmware to clear the pending status of interrupts after they have been serviced. The NVIC normally clears the pending status automatically after the ISR finishes. But writing to the ICPR gives software manual control over clearing pending interrupts.
This can be useful when implementing priority based interrupt servicing, where lower priority interrupts may need to be cleared when higher priority ones occur.
How to Use NVIC Registers in Firmware
Here is a typical workflow for using the NVIC registers in a Cortex-M firmware application:
- On startup, configure ISER and ICER to enable required interrupts and disable any unnecessary ones.
- Implement Interrupt Service Routines (ISRs) for the enabled interrupts.
- Configure interrupt priorities using the NVIC priority registers if needed.
- Globally enable interrupts by clearing PRIMASK.
- In the main application, use ISPR to trigger interrupts manually for testing.
- In the ISRs, clear pending interrupts using ICPR after servicing.
- Manage interrupt enabling during runtime using ISER and ICER as needed.
Properly configuring the NVIC registers is an important part of developing Cortex-M firmware. Using the ISER, ICER, ISPR and ICPR registers in combination provides full control over interrupt handling in the application.
Example Firmware Usage
Here is an example of how the NVIC registers could be used within a Cortex-M firmware application: // ISER – enable IRQ6 interrupt NVIC->ISER[0] = 1 << 6; // ICER – disable IRQ3 interrupt NVIC->ICER[0] = 1 << 3; // ISPR – trigger IRQ10 interrupt manually NVIC->ISPR[0] = 1 << 10; // IRQ6 ISR void TIM2_IRQHandler() { //clear pending status NVIC->ICPR[0] = 1 << 6; //service interrupt //… }
This demonstrates enabling and disabling interrupts using ISER and ICER, manually triggering an interrupt with ISPR, and clearing the pending status after servicing using ICPR.
NVIC Register Summary
To summarize the key points on NVIC registers:
- ISER – Used to enable interrupts by setting bits that correspond to interrupts.
- ICER – Used to disable interrupts by clearing bits.
- ISPR – Used to force interrupts into pending state by setting bits.
- ICPR – Used to clear the pending state of interrupts by clearing bits.
- The registers allow full control over interrupt enabling, pending status, and disabling.
- Proper management of NVIC registers is key for interrupt handling in Cortex-M firmware.
So in summary, the ISER, ICER, ISPR, and ICPR registers give firmware complete access to manage interrupts in Cortex-M microcontrollers. Using them appropriately can greatly simplify interrupt management and configuration.
Frequently Asked Questions
1. Do I need to enable an interrupt in the ISER before setting it pending with ISPR?
No, you can set a pending interrupt in ISPR without first enabling it in ISER. This allows pending interrupts to be set for disabled interrupts too. The actual exception/ISR will only happen if the interrupt is also enabled.
2. How are the NVIC registers initialized on chip reset?
The ISER and ICER retain their state across resets. ISPR and ICPR are cleared to zero on reset. So any previously enabled interrupts in ISER remain enabled, while pending states are cleared.
3. Do I need to clear pending interrupts in the ISR using ICPR? In most cases no, as the NVIC will automatically clear pending status once the ISR completes. But ICPR allows firmware to manually clear pending interrupts, which can be useful in certain priority based interrupt servicing schemes.
4. What is the bit width of the NVIC registers?
The NVIC registers are 32 bits wide. So each register allows enabling/disabling/pending of up to 32 interrupts based on the interrupt number. For MCUs with more interrupts, multiple instances of the registers are chained together.
5. Can I access the NVIC registers directly?
Yes, the NVIC registers sit in the memory map of the Cortex-M processor and can be directly accessed using load/store instructions. The addresses are available in the chip reference manual.
Conclusion
The ISER, ICER, ISPR and ICPR registers of the NVIC provide fine-grained control over interrupt configuration in Cortex-M processors. Using them appropriately can simplify interrupt management in firmware applications. These registers allow interrupts to be enabled, disabled, triggered manually, and have their pending status cleared from software.
Properly configuring the NVIC is a key step in developing robust interrupt-driven applications on Cortex-M microcontrollers. Understanding the capabilities of these registers helps firmware engineers utilize them most effectively.