1 /******************************************************************************
2 *  Filename:       interrupt_doc.h
3 *
4 *  Copyright (c) 2015 - 2022, Texas Instruments Incorporated
5 *  All rights reserved.
6 *
7 *  Redistribution and use in source and binary forms, with or without
8 *  modification, are permitted provided that the following conditions are met:
9 *
10 *  1) Redistributions of source code must retain the above copyright notice,
11 *     this list of conditions and the following disclaimer.
12 *
13 *  2) Redistributions in binary form must reproduce the above copyright notice,
14 *     this list of conditions and the following disclaimer in the documentation
15 *     and/or other materials provided with the distribution.
16 *
17 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
18 *     be used to endorse or promote products derived from this software without
19 *     specific prior written permission.
20 *
21 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 *  POSSIBILITY OF SUCH DAMAGE.
32 *
33 ******************************************************************************/
34 //! \addtogroup interrupt_api
35 //! @{
36 //! \section sec_interrupt Introduction
37 //!
38 //! The interrupt controller API provides a set of functions for dealing with the
39 //! Nested Vectored Interrupt Controller (NVIC). Functions are provided to enable
40 //! and disable interrupts, register interrupt handlers, and set the priority of
41 //! interrupts.
42 //!
43 //! The event sources that trigger the interrupt lines in the NVIC are controlled by
44 //! the MCU event fabric. All event sources are statically connected to the NVIC interrupt lines
45 //! except one which is programmable. For more information about the MCU event fabric, see the
46 //! [MCU event fabric API](\ref event_api).
47 //!
48 //! \section sec_interrupt_api API
49 //!
50 //! Interrupts and system exceptions must be individually enabled and disabled through:
51 //! - \ref IntEnable()
52 //! - \ref IntDisable()
53 //!
54 //! The global CPU interrupt can be enabled and disabled with the following functions:
55 //! - \ref IntMasterEnable()
56 //! - \ref IntMasterDisable()
57 //!
58 //! This does not affect the individual interrupt enable states. Masking of the CPU
59 //! interrupt can be used as a simple critical section (only an NMI can interrupt the
60 //! CPU while the CPU interrupt is disabled), although masking the CPU
61 //! interrupt can increase the interrupt response time.
62 //!
63 //! It is possible to access the NVIC to see if any interrupts are pending and manually
64 //! clear pending interrupts which have not yet been serviced or set a specific interrupt as
65 //! pending to be handled based on its priority. Pending interrupts are cleared automatically
66 //! when the interrupt is accepted and executed. However, the event source which caused the
67 //! interrupt might need to be cleared manually to avoid re-triggering the corresponding interrupt.
68 //! The functions to read, clear, and set pending interrupts are:
69 //! - \ref IntPendGet()
70 //! - \ref IntPendClear()
71 //! - \ref IntPendSet()
72 //!
73 //! The interrupt prioritization in the NVIC allows handling of higher priority interrupts
74 //! before lower priority interrupts, as well as allowing preemption of lower priority interrupt
75 //! handlers by higher priority interrupts.
76 //! The device supports eight priority levels from 0 to 7 with 0 being the highest priority.
77 //! The priority of each interrupt source can be set and examined using:
78 //! - \ref IntPrioritySet()
79 //! - \ref IntPriorityGet()
80 //!
81 //! Interrupts can be masked based on their priority such that interrupts with the same or lower
82 //! priority than the mask are effectively disabled. This can be configured with:
83 //! - \ref IntPriorityMaskSet()
84 //! - \ref IntPriorityMaskGet()
85 //!
86 //! Subprioritization is also possible. Instead of having three bits of preemptable
87 //! prioritization (eight levels), the NVIC can be configured for 3 - M bits of
88 //! preemptable prioritization and M bits of subpriority. In this scheme, two
89 //! interrupts with the same preemptable prioritization but different subpriorities
90 //! do not cause a preemption. Instead, tail chaining is used to process
91 //! the two interrupts back-to-back.
92 //! If two interrupts with the same priority (and subpriority if so configured) are
93 //! asserted at the same time, the one with the lower interrupt number is
94 //! processed first.
95 //! Subprioritization is handled by:
96 //! - \ref IntPriorityGroupingSet()
97 //! - \ref IntPriorityGroupingGet()
98 //!
99 //! \section sec_interrupt_table Interrupt Vector Table
100 //!
101 //! The interrupt vector table can be configured in one of two ways:
102 //! - Statically (at compile time): Vector table is placed in Flash and each entry has a fixed
103 //!   pointer to an interrupt handler (ISR).
104 //! - Dynamically (at runtime): Vector table is placed in SRAM and each entry can be changed
105 //!   (registered or unregistered) at runtime. This allows a single interrupt to trigger different
106 //!   interrupt handlers (ISRs) depending on which interrupt handler is registered at the time the
107 //!   System CPU responds to the interrupt.
108 //!
109 //! When configured, the interrupts must be explicitly enabled in the NVIC through \ref IntEnable()
110 //! before the CPU can respond to the interrupt (in addition to any interrupt enabling required
111 //! within the peripheral).
112 //!
113 //! \subsection sec_interrupt_table_static Static Vector Table
114 //!
115 //! Static registration of interrupt handlers is accomplished by editing the interrupt handler
116 //! table in the startup code of the application. Texas Instruments provides startup files for
117 //! each supported compiler ( \ti_code{startup_<compiler>.c} ) and these startup files include
118 //! a default static interrupt vector table.
119 //! All entries, except ResetISR, are declared as \c extern with weak assignment to a default
120 //! interrupt handler. This allows the user to declare and define a function (in the user's code)
121 //! with the same name as an entry in the vector table. At compile time, the linker then replaces
122 //! the pointer to the default interrupt handler in the vector table with the pointer to the
123 //! interrupt handler defined by the user.
124 //!
125 //! Statically configuring the interrupt table provides the fastest interrupt response time
126 //! because the stacking operation (a write to SRAM on the data bus) is performed in parallel
127 //! with the interrupt handler table fetch (a read from Flash on the instruction bus), as well
128 //! as the prefetch of the interrupt handler (assuming it is also in Flash).
129 //!
130 //! \subsection sec_interrupt_table_dynamic Dynamic Vector Table
131 //!
132 //! Alternatively, interrupts can be registered in the vector table at runtime, thus dynamically.
133 //! The dynamic vector table is placed in SRAM and the code can then modify the pointers to
134 //! interrupt handlers throughout the application.
135 //!
136 //! DriverLib uses these two functions to modify the dynamic vector table:
137 //! - \ref IntRegister() : Write a pointer to an interrupt handler into the vector table.
138 //! - \ref IntUnregister() : Write pointer to default interrupt handler into the vector table.
139 //!
140 //! \note First call to \ref IntRegister() initializes the vector table in SRAM by copying the
141 //! static vector table from Flash and forcing the NVIC to use the dynamic vector table from
142 //! this point forward. If using the dynamic vector table it is highly recommended to
143 //! initialize it during the setup phase of the application. The NVIC uses the static vector
144 //! table in Flash until the application initializes the dynamic vector table in SRAM.
145 //!
146 //! Runtime configuration of interrupts adds a small latency to the interrupt response time
147 //! because the stacking operation (a write to SRAM on the data bus) and the interrupt handler
148 //! fetch from the vector table (a read from SRAM on the instruction bus) must be performed
149 //! sequentially.
150 //!
151 //! The dynamic vector table, \ref g_pfnRAMVectors, is placed in SRAM in the section called
152 //! \c vtable_ram which is a section defined in the linker file. By default the linker file
153 //! places this section at the start of the SRAM but this is configurable by the user.
154 //!
155 //! \warning Runtime configuration of interrupt handlers requires that the interrupt
156 //! handler table is placed on a 256-byte boundary in SRAM (typically, this is
157 //! at the beginning of SRAM). Failure to do so results in an incorrect vector
158 //! address being fetched in response to an interrupt.
159 //!
160 //! @}
161