1 /******************************************************************************
2 * Filename: interrupt.h
3 *
4 * Description: Defines and prototypes for the NVIC Interrupt Controller
5 *
6 * Copyright (c) 2022-2023 Texas Instruments Incorporated
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1) Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * 2) Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * 3) Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ******************************************************************************/
35
36 #ifndef __INTERRUPT_H__
37 #define __INTERRUPT_H__
38
39 //*****************************************************************************
40 //
41 //! \addtogroup system_cpu_group
42 //! @{
43 //! \addtogroup interrupt_api
44 //! @{
45 //
46 //*****************************************************************************
47
48 //*****************************************************************************
49 //
50 // If building with a C++ compiler, make all of the definitions in this header
51 // have a C binding.
52 //
53 //*****************************************************************************
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57
58 #include <stdbool.h>
59 #include <stdint.h>
60
61 #include "../inc/hw_ints.h"
62 #include "../inc/hw_types.h"
63
64 #include "../cmsis/cc23x0r5.h"
65 #include "../cmsis/core/core_cm0plus.h"
66
67 #include "cpu.h"
68
69 //*****************************************************************************
70 //
71 // API Functions and prototypes
72 //
73 //*****************************************************************************
74
75 //*****************************************************************************
76 //
77 //! \brief Registers a function as an interrupt handler in the dynamic vector table.
78 //!
79 //! \note Only use this function if you want to use the dynamic vector table (in SRAM)!
80 //!
81 //! This function writes a function pointer to the dynamic interrupt vector table
82 //! in SRAM to register the function as an interrupt handler (ISR). When the corresponding
83 //! interrupt occurs, and it has been enabled (see \ref IntEnable()), the function
84 //! pointer is fetched from the dynamic vector table, and the System CPU will
85 //! execute the interrupt handler.
86 //!
87 //! \note The first call to this function (directly or indirectly via a peripheral
88 //! driver interrupt register function) copies the interrupt vector table from
89 //! Flash to SRAM. NVIC uses the static vector table (in Flash) until this function
90 //! is called.
91 //!
92 //! \param intNum specifies the index in the vector table to modify.
93 //! - System exceptions:
94 //! - INT_NMI_FAULT
95 //! - INT_HARD_FAULT
96 //! - INT_SVCALL
97 //! - INT_PENDSV
98 //! - INT_SYSTICK
99 //! - Interrupts:
100 //! - INT_CPUIRQ0
101 //! - INT_CPUIRQ1
102 //! - INT_CPUIRQ2
103 //! - INT_CPUIRQ3
104 //! - INT_CPUIRQ4
105 //! - INT_GPIO_COMB
106 //! - INT_LRFD_IRQ0
107 //! - INT_LRFD_IRQ1
108 //! - INT_DMA_DONE_COMB
109 //! - INT_AES_COMB
110 //! - INT_SPI0_COMB
111 //! - INT_UART0_COMB
112 //! - INT_I2C0_IRQ
113 //! - INT_LGPT0_COMB
114 //! - INT_LGPT1_COMB
115 //! - INT_ADC_COMB
116 //! - INT_CPUIRQ16
117 //! - INT_LGPT2_COMB
118 //! - INT_LGPT3_COMB
119 //!
120 //! \param handler is a pointer to the function to register as interrupt handler.
121 //!
122 //! \return None.
123 //!
124 //! \sa \ref IntUnregister(), \ref IntEnable()
125 //
126 //*****************************************************************************
127 extern void IntRegister(uint32_t intNum, void (*handler)(void));
128
129 //*****************************************************************************
130 //
131 //! \brief Unregisters an interrupt handler in the dynamic vector table.
132 //!
133 //! This function removes an interrupt handler from the dynamic vector table and
134 //! replaces it with the default interrupt handler \ref IntDefaultHandler().
135 //!
136 //! \note Remember to disable the interrupt before removing its interrupt handler
137 //! from the vector table.
138 //!
139 //! \param intNum specifies the index in the vector table to modify.
140 //! - See \ref IntRegister() for list of valid arguments.
141 //!
142 //! \return None.
143 //!
144 //! \sa \ref IntRegister(), \ref IntDisable()
145 //
146 //*****************************************************************************
147 extern void IntUnregister(uint32_t intNum);
148
149 //*****************************************************************************
150 //
151 //! \brief Sets the priority of an interrupt.
152 //!
153 //! This function sets the priority of an interrupt, including system exceptions.
154 //! When multiple interrupts are asserted simultaneously, the ones with the highest
155 //! priority are processed before the lower priority interrupts. Smaller numbers
156 //! correspond to higher interrupt priorities thus priority 0 is the highest
157 //! interrupt priority.
158 //!
159 //! \warning On Cortex M0+, changing interrupt priorities dynamically is not
160 //! supported. In order to change the priority of an interrupt, after it has
161 //! been enabled, the following steps must be followed:
162 //! - Disable the interrupt whose priority needs to be changed
163 //! - Change the priority
164 //! - Re-enable the interrupt
165 //! This is taken care of by the IntSetPriority function.
166 //!
167 //! \warning It is possible to lose an interrupt while its priority is being
168 //! changed, since that interrupt needs to be disabled to be able change its
169 //! priority.
170 //!
171 //! \warning This function does not support setting priority of interrupt
172 //! vectors one through three which are:
173 //! - 1: Reset handler
174 //! - 2: NMI handler
175 //! - 3: Hard fault handler
176 //!
177 //! \param intNum specifies the index in the vector table to change priority for.
178 //! - System exceptions:
179 //! - INT_SVCALL
180 //! - INT_PENDSV
181 //! - INT_SYSTICK
182 //! - Interrupts:
183 //! - INT_CPUIRQ0
184 //! - INT_CPUIRQ1
185 //! - INT_CPUIRQ2
186 //! - INT_CPUIRQ3
187 //! - INT_CPUIRQ4
188 //! - INT_GPIO_COMB
189 //! - INT_LRFD_IRQ0
190 //! - INT_LRFD_IRQ1
191 //! - INT_DMA_DONE_COMB
192 //! - INT_AES_COMB
193 //! - INT_SPI0_COMB
194 //! - INT_UART0_COMB
195 //! - INT_I2C0_IRQ
196 //! - INT_LGPT0_COMB
197 //! - INT_LGPT1_COMB
198 //! - INT_ADC_COMB
199 //! - INT_CPUIRQ16
200 //! - INT_LGPT2_COMB
201 //! - INT_LGPT3_COMB
202 //!
203 //! \param priority specifies the priority of the interrupt.
204 //! - \ref INT_PRI_LEVEL0 : Highest priority.
205 //! - \ref INT_PRI_LEVEL1
206 //! - \ref INT_PRI_LEVEL2
207 //! - \ref INT_PRI_LEVEL3 : Lowest priority.
208 //!
209 //! \return None
210 //
211 //*****************************************************************************
212 extern void IntSetPriority(uint32_t intNum, uint8_t priority);
213
214 //*****************************************************************************
215 //
216 //! \brief Gets the priority of an interrupt.
217 //!
218 //! This function gets the priority of an interrupt.
219 //!
220 //! \warning This function does not support getting priority of interrupt vectors
221 //! one through three which are:
222 //! - 1: Reset handler
223 //! - 2: NMI handler
224 //! - 3: Hard fault handler
225 //!
226 //! \param intNum specifies the index in the vector table to read priority of.
227 //! - See \ref IntSetPriority() for list of valid arguments.
228 //!
229 //! \return Returns the interrupt priority:
230 //! - \ref INT_PRI_LEVEL0 : Highest priority.
231 //! - \ref INT_PRI_LEVEL1
232 //! - \ref INT_PRI_LEVEL2
233 //! - \ref INT_PRI_LEVEL3 : Lowest priority.
234 //
235 //*****************************************************************************
236 extern int32_t IntGetPriority(uint32_t intNum);
237
238 //*****************************************************************************
239 //
240 //! \brief Check whether an interrupt is enabled.
241 //!
242 //! This function checks whether an interrupt is enabled in the NVIC.
243 //!
244 //! \param intNum specifies the index in the vector table to check.
245 //!
246 //! \return Whether the interrupt is enabled or not
247 //!
248 //! \sa \ref IntDisable()
249 //! \sa \ref IntEnable()
250 //
251 //*****************************************************************************
252 extern bool IntIsEnabled(uint32_t intNum);
253
254 //*****************************************************************************
255 //
256 //! \brief Enables an interrupt or system exception.
257 //!
258 //! This function enables the specified interrupt in the interrupt controller.
259 //!
260 //! \note If a fault condition occurs while the corresponding system exception
261 //! is disabled, the fault is treated as a Hard Fault.
262 //!
263 //! \param intNum specifies the index in the vector table to enable.
264 //!
265 //! \return None
266 //!
267 //! \sa \ref IntDisable()
268 //
269 //*****************************************************************************
270 extern void IntEnable(uint32_t intNum);
271
272 //*****************************************************************************
273 //
274 //! \brief Disables an interrupt or system exception.
275 //!
276 //! This function disables the specified interrupt in the interrupt controller.
277 //!
278 //! \param intNum specifies the index in the vector table to disable.
279 //! - See \ref IntEnable() for list of valid arguments.
280 //!
281 //! \return None
282 //!
283 //! \sa \ref IntEnable()
284 //
285 //*****************************************************************************
286 extern void IntDisable(uint32_t intNum);
287
288 //*****************************************************************************
289 //
290 //! \brief Pends an interrupt.
291 //!
292 //! This function pends the specified interrupt in the interrupt controller.
293 //! This causes the interrupt controller to execute the corresponding interrupt
294 //! handler at the next available time, based on the current interrupt state
295 //! priorities.
296 //!
297 //! This interrupt controller automatically clears the pending interrupt once the
298 //! interrupt handler is executed.
299 //!
300 //! \param intNum specifies the index in the vector table to pend.
301 //!
302 //! \return None
303 //!
304 //! \sa \ref IntEnable()
305 //
306 //*****************************************************************************
307 extern void IntSetPend(uint32_t intNum);
308
309 //*****************************************************************************
310 //
311 //! \brief Checks if an interrupt is pending.
312 //!
313 //! This function checks the interrupt controller to see if an interrupt is pending.
314 //!
315 //! The interrupt must be enabled in order for the corresponding interrupt handler
316 //! to be executed, so an interrupt can be pending waiting to be enabled or waiting
317 //! for an interrupt of higher priority to be done executing.
318 //!
319 //! \note This function does not support reading pending status for system exceptions
320 //! (vector table indexes <16).
321 //!
322 //! \param intNum specifies the index in the vector table to check pending
323 //! status for.
324 //! - See \ref IntSetPend() for list of valid arguments (except system exceptions).
325 //!
326 //! \return Returns:
327 //! - \c true : Specified interrupt is pending.
328 //! - \c false : Specified interrupt is not pending.
329 //
330 //*****************************************************************************
331 extern bool IntGetPend(uint32_t intNum);
332
333 //*****************************************************************************
334 //
335 //! \brief Unpends an interrupt.
336 //!
337 //! This function unpends the specified interrupt in the interrupt controller.
338 //! This causes any previously generated interrupts that have not been handled yet
339 //! (due to higher priority interrupts or the interrupt no having been enabled
340 //! yet) to be discarded.
341 //!
342 //! \note It is not possible to unpend the NMI because it takes effect
343 //! immediately when being pended.
344 //!
345 //! \param intNum specifies the index in the vector table to unpend.
346 //! - See \ref IntSetPend() for list of valid arguments (except NMI).
347 //!
348 //! \return None
349 //
350 //*****************************************************************************
351 extern void IntClearPend(uint32_t intNum);
352
353 //*****************************************************************************
354 //
355 //! \brief Enables the CPU interrupt.
356 //!
357 //! Allows the CPU to respond to interrupts.
358 //!
359 //! \return Returns:
360 //! - \c true : Interrupts were disabled and are now enabled.
361 //! - \c false : Interrupts were already enabled when the function was called.
362 //
363 //*****************************************************************************
IntEnableMaster(void)364 __STATIC_INLINE bool IntEnableMaster(void)
365 {
366 uint32_t interruptsDisabled = __get_PRIMASK();
367 // Enable CPU interrupts.
368 __enable_irq();
369 return (interruptsDisabled);
370 }
371
372 //*****************************************************************************
373 //
374 //! \brief Disables the CPU interrupts with configurable priority.
375 //!
376 //! Prevents the CPU from receiving interrupts except NMI and hard fault. This
377 //! does not affect the set of interrupts enabled in the interrupt controller;
378 //! it just gates the interrupt from the interrupt controller to the CPU.
379 //!
380 //! \return Returns:
381 //! - \c true : Interrupts were already disabled when the function was called.
382 //! - \c false : Interrupts were enabled and are now disabled.
383 //
384 //*****************************************************************************
IntDisableMaster(void)385 __STATIC_INLINE bool IntDisableMaster(void)
386 {
387 uint32_t interruptsDisabled = __get_PRIMASK();
388 // Disable CPU interrupts.
389 __disable_irq();
390 return (interruptsDisabled);
391 }
392
393 //*****************************************************************************
394 //
395 // Mark the end of the C bindings section for C++ compilers.
396 //
397 //*****************************************************************************
398 #ifdef __cplusplus
399 }
400 #endif
401
402 //*****************************************************************************
403 //
404 //! Close the Doxygen group.
405 //! @}
406 //! @}
407 //
408 //*****************************************************************************
409
410 #endif // __INTERRUPT_H__
411