15.6 Enabling/Disabling Interrupts
Each interrupt source can be individually enabled or disabled. One
interrupt enable bit for each IRQ is allocated in the Interrupt Enable Control registers
(IECn). Setting an interrupt enable bit to one (1
) enables the
corresponding interrupt; clearing the interrupt enable bit to zero (0
)
disables the corresponding interrupt. When the device comes out of Reset, all interrupt
enable bits are cleared to zero.
The safe method of enabling and disabling peripheral interrupts is to use
the __write_to_IEC()
macro, which is defined in the device header files.
This is helpful because some devices require one cycle of delay for this to take effect,
but some require two. A different version of __write_to_IEC()
will be
generated based on device-specific information.
In addition, the processor has a disable interrupt instruction
(DISI
) that can disable all interrupts for a specified number of
instruction cycles.The DISI instruction can be used in a C program through the use of:
__builtin_disi
For example:
__builtin_disi(16);
will emit the specified DISI instruction at the point it appears in the source program. A disadvantage of using DISI in this way is that the C programmer cannot always be sure how the C compiler will translate C source to machine instructions, so it may be difficult to determine the cycle count for the DISI instruction. It is possible to get around this difficulty by bracketing the code that is to be protected from interrupts by DISI instructions, the first of which sets the cycle count to the maximum value, and the second of which sets the cycle count to zero. For example,
__builtin_disi(0x3FFF); /* disable interrupts */
/* ... protected C code ... */
__builtin_disi(0x0000); /* enable interrupts */
An alternative approach is to write directly to the DISICNT register to
enable interrupts. The DISICNT register may be modified only after a DISI
instruction has been issued and if the contents of the DISICNT register are not zero.
__builtin_disi(0x3FFF); /* disable interrupts */
/* ... protected C code ... */
DISICNT = 0x0000; /* enable interrupts */
For some applications, it may be necessary to disable level 7 interrupts
as well. These can only be disabled through the modification of the COROCON
IPL
field. The provided support files contain some useful preprocessor macro
functions to help you safely modify the IPL value. These macros are:
SET_CPU_IPL(ipl)
SET_AND_SAVE_CPU_IPL(save_to, ipl)
RESTORE_CPU_IPL(saved_to)
For example, you may wish to protect a section of code from interrupt. The
following code will adjust the current IPL
setting and restore the
IPL
to its previous value.
void foo(void) {
int current_cpu_ipl;
SET_AND_SAVE_CPU_IPL(current_cpu_ipl, 7); /* disable interrupts */
/* protected code here */
RESTORE_CPU_IPL(current_cpu_ipl);
}