1 /******************************************************************************
2 * Filename: interrupt.h
3 * Revised: 2015-07-24 15:00:55 +0200 (Fri, 24 Jul 2015)
4 * Revision: 44203
5 *
6 * Description: Defines and prototypes for the NVIC Interrupt Controller
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 //*****************************************************************************
40 //
41 //! \addtogroup system_cpu_group
42 //! @{
43 //! \addtogroup interrupt_api
44 //! @{
45 //
46 //*****************************************************************************
47
48 #ifndef __INTERRUPT_H__
49 #define __INTERRUPT_H__
50
51 //*****************************************************************************
52 //
53 // If building with a C++ compiler, make all of the definitions in this header
54 // have a C binding.
55 //
56 //*****************************************************************************
57 #ifdef __cplusplus
58 extern "C"
59 {
60 #endif
61
62 #include <stdbool.h>
63 #include <stdint.h>
64 #include <inc/hw_ints.h>
65 #include <inc/hw_types.h>
66 #include <inc/hw_nvic.h>
67 #include <driverlib/debug.h>
68 #include <driverlib/cpu.h>
69
70 //*****************************************************************************
71 //
72 // Support for DriverLib in ROM:
73 // This section renames all functions that are not "static inline", so that
74 // calling these functions will default to implementation in flash. At the end
75 // of this file a second renaming will change the defaults to implementation in
76 // ROM for available functions.
77 //
78 // To force use of the implementation in flash, e.g. for debugging:
79 // - Globally: Define DRIVERLIB_NOROM at project level
80 // - Per function: Use prefix "NOROM_" when calling the function
81 //
82 //*****************************************************************************
83 #if !defined(DOXYGEN)
84 #define IntRegister NOROM_IntRegister
85 #define IntUnregister NOROM_IntUnregister
86 #define IntPriorityGroupingSet NOROM_IntPriorityGroupingSet
87 #define IntPriorityGroupingGet NOROM_IntPriorityGroupingGet
88 #define IntPrioritySet NOROM_IntPrioritySet
89 #define IntPriorityGet NOROM_IntPriorityGet
90 #define IntEnable NOROM_IntEnable
91 #define IntDisable NOROM_IntDisable
92 #define IntPendSet NOROM_IntPendSet
93 #define IntPendGet NOROM_IntPendGet
94 #define IntPendClear NOROM_IntPendClear
95 #endif
96
97 //*****************************************************************************
98 //
99 // Macro to generate an interrupt priority mask based on the number of bits
100 // of priority supported by the hardware. For CC26xx the number of priority
101 // bit is 3 as defined in <tt>hw_types.h</tt>. The priority mask is
102 // defined as
103 //
104 // INT_PRIORITY_MASK = ((0xFF << (8 - NUM_PRIORITY_BITS)) & 0xFF)
105 //
106 //*****************************************************************************
107 #define INT_PRIORITY_MASK 0x000000E0
108 #define INT_PRI_LEVEL0 0x00000000
109 #define INT_PRI_LEVEL1 0x00000020
110 #define INT_PRI_LEVEL2 0x00000040
111 #define INT_PRI_LEVEL3 0x00000060
112 #define INT_PRI_LEVEL4 0x00000080
113 #define INT_PRI_LEVEL5 0x000000A0
114 #define INT_PRI_LEVEL6 0x000000C0
115 #define INT_PRI_LEVEL7 0x000000E0
116
117 //*****************************************************************************
118 //
119 // API Functions and prototypes
120 //
121 //*****************************************************************************
122
123 //*****************************************************************************
124 //
125 //! \brief Enables the processor interrupt.
126 //!
127 //! Allows the processor to respond to interrupts. This does not affect the
128 //! set of interrupts enabled in the interrupt controller; it just gates the
129 //! single interrupt from the controller to the processor.
130 //!
131 //! \return Returns:
132 //! - \c true : Interrupts were disabled and are now enabled.
133 //! - \c false : Interrupts were already enabled when the function was called.
134 //
135 //*****************************************************************************
136 __STATIC_INLINE bool
IntMasterEnable(void)137 IntMasterEnable(void)
138 {
139 //
140 // Enable processor interrupts.
141 //
142 return(CPUcpsie());
143 }
144
145 //*****************************************************************************
146 //
147 //! \brief Disables the processor interrupt.
148 //!
149 //! Prevents the processor from receiving interrupts. This does not affect the
150 //! set of interrupts enabled in the interrupt controller; it just gates the
151 //! single interrupt from the controller to the processor.
152 //!
153 //! \return Returns:
154 //! - \c true : Interrupts were already disabled when the function was called.
155 //! - \c false : Interrupts were enabled and are now disabled.
156 //
157 //*****************************************************************************
158 __STATIC_INLINE bool
IntMasterDisable(void)159 IntMasterDisable(void)
160 {
161 //
162 // Disable processor interrupts.
163 //
164 return(CPUcpsid());
165 }
166
167 //*****************************************************************************
168 //
169 //! \brief Registers a function to be called when an interrupt occurs.
170 //!
171 //! This function is used to specify the handler function to be called when the
172 //! given interrupt is asserted to the processor. When the interrupt occurs,
173 //! if it is enabled (via \ref IntEnable()), the handler function will be called in
174 //! interrupt context. Since the handler function can preempt other code, care
175 //! must be taken to protect memory or peripherals that are accessed by the
176 //! handler and other non-handler code.
177 //!
178 //! \note The use of this function (directly or indirectly via a peripheral
179 //! driver interrupt register function) moves the interrupt vector table from
180 //! flash to SRAM. Therefore, care must be taken when linking the application
181 //! to ensure that the SRAM vector table is located at the beginning of SRAM;
182 //! otherwise NVIC will not look in the correct portion of memory for the
183 //! vector table (it requires the vector table be on a 1 kB memory alignment).
184 //! Normally, the SRAM vector table is so placed via the use of linker scripts.
185 //!
186 //! \param ui32Interrupt specifies the interrupt in question.
187 //! \param pfnHandler is a pointer to the function to be called.
188 //!
189 //! \return None.
190 //
191 //*****************************************************************************
192 extern void IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void));
193
194 //*****************************************************************************
195 //
196 //! \brief Unregisters the function to be called when an interrupt occurs.
197 //!
198 //! This function is used to indicate that no handler should be called when the
199 //! given interrupt is asserted to the processor. The interrupt source will be
200 //! automatically disabled (via \ref IntDisable()) if necessary.
201 //!
202 //! \param ui32Interrupt specifies the interrupt in question.
203 //!
204 //! \return None.
205 //!
206 //! \sa \ref IntRegister() for important information about registering interrupt
207 //! handlers.
208 //
209 //*****************************************************************************
210 extern void IntUnregister(uint32_t ui32Interrupt);
211
212 //*****************************************************************************
213 //
214 //! \brief Sets the priority grouping of the interrupt controller.
215 //!
216 //! This function specifies the split between preemptable priority levels and
217 //! subpriority levels in the interrupt priority specification. The range of
218 //! the grouping values are dependent upon the hardware implementation; on
219 //! the CC26xx family, three bits are available for hardware interrupt
220 //! prioritization and therefore priority grouping values of three through
221 //! seven have the same effect.
222 //!
223 //! \param ui32Bits specifies the number of bits of preemptable priority.
224 //!
225 //! \return None
226 //
227 //*****************************************************************************
228 extern void IntPriorityGroupingSet(uint32_t ui32Bits);
229
230 //*****************************************************************************
231 //
232 //! \brief Gets the priority grouping of the interrupt controller.
233 //!
234 //! This function returns the split between preemptable priority levels and
235 //! subpriority levels in the interrupt priority specification.
236 //!
237 //! \return Returns the number of bits of preemptable priority.
238 //
239 //*****************************************************************************
240 extern uint32_t IntPriorityGroupingGet(void);
241
242 //*****************************************************************************
243 //
244 //! \brief Sets the priority of an interrupt.
245 //!
246 //! This function is used to set the priority of an interrupt. When multiple
247 //! interrupts are asserted simultaneously, the ones with the highest priority
248 //! are processed before the lower priority interrupts. Smaller numbers
249 //! correspond to higher interrupt priorities; priority 0 is the highest
250 //! interrupt priority.
251 //!
252 //! The hardware priority mechanism will only look at the upper N bits of the
253 //! priority level (where N is 3 for cc26xx), so any prioritization must be
254 //! performed in those bits. The remaining bits can be used to sub-prioritize
255 //! the interrupt sources, and may be used by the hardware priority mechanism
256 //! on a future part. This arrangement allows priorities to migrate to
257 //! different NVIC implementations without changing the gross prioritization
258 //! of the interrupts.
259 //!
260 //! \param ui32Interrupt specifies the interrupt in question.
261 //! \param ui8Priority specifies the priority of the interrupt.
262 //! - \ref INT_PRI_LEVEL0 : Highest priority.
263 //! - \ref INT_PRI_LEVEL1
264 //! - \ref INT_PRI_LEVEL2
265 //! - \ref INT_PRI_LEVEL3
266 //! - \ref INT_PRI_LEVEL4
267 //! - \ref INT_PRI_LEVEL5
268 //! - \ref INT_PRI_LEVEL6
269 //! - \ref INT_PRI_LEVEL7 : Lowest priority.
270 //!
271 //! \return None
272 //
273 //*****************************************************************************
274 extern void IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority);
275
276 //*****************************************************************************
277 //
278 //! \brief Gets the priority of an interrupt.
279 //!
280 //! This function gets the priority of an interrupt.
281 //!
282 //! \param ui32Interrupt specifies the interrupt in question.
283 //!
284 //! \return Returns the interrupt priority:
285 //! - (-1) : Invalid interrupt specified as parameter!
286 //! - \ref INT_PRI_LEVEL0 : Highest priority.
287 //! - \ref INT_PRI_LEVEL1
288 //! - \ref INT_PRI_LEVEL2
289 //! - \ref INT_PRI_LEVEL3
290 //! - \ref INT_PRI_LEVEL4
291 //! - \ref INT_PRI_LEVEL5
292 //! - \ref INT_PRI_LEVEL6
293 //! - \ref INT_PRI_LEVEL7 : Lowest priority.
294 //
295 //*****************************************************************************
296 extern int32_t IntPriorityGet(uint32_t ui32Interrupt);
297
298 //*****************************************************************************
299 //
300 //! \brief Enables an interrupt.
301 //!
302 //! The specified interrupt is enabled in the interrupt controller. Other
303 //! enables for the interrupt (such as at the peripheral level) are unaffected
304 //! by this function.
305 //!
306 //! \param ui32Interrupt specifies the interrupt to be enabled.
307 //!
308 //! \return None
309 //
310 //*****************************************************************************
311 extern void IntEnable(uint32_t ui32Interrupt);
312
313 //*****************************************************************************
314 //
315 //! \brief Disables an interrupt.
316 //!
317 //! The specified interrupt is disabled in the interrupt controller. Other
318 //! enables for the interrupt (such as at the peripheral level) are unaffected
319 //! by this function.
320 //!
321 //! \param ui32Interrupt specifies the interrupt to be disabled.
322 //!
323 //! \return None
324 //
325 //*****************************************************************************
326 extern void IntDisable(uint32_t ui32Interrupt);
327
328 //*****************************************************************************
329 //
330 //! \brief Pends an interrupt.
331 //!
332 //! The specified interrupt is pended in the interrupt controller. This will
333 //! cause the interrupt controller to execute the corresponding interrupt
334 //! handler at the next available time, based on the current interrupt state
335 //! priorities. For example, if called by a higher priority interrupt handler,
336 //! the specified interrupt handler will not be called until after the current
337 //! interrupt handler has completed execution. The interrupt must have been
338 //! enabled for it to be called.
339 //!
340 //! \param ui32Interrupt specifies the interrupt to be pended.
341 //!
342 //! \return None
343 //
344 //*****************************************************************************
345 extern void IntPendSet(uint32_t ui32Interrupt);
346
347 //*****************************************************************************
348 //
349 //! \brief Query whether an interrupt is pending.
350 //!
351 //! This function will check whether the specified interrupt is pending in the
352 //! interrupt controller. The interrupt must have been enabled for it to be
353 //! called, so an interrupt can very well be pending waiting to be enabled or
354 //! waiting for an interrupt of higher priority to be done executing.
355 //!
356 //! \note This function does not support the lower 16 IRQ vectors which are
357 //! hardware defined for the System CPU.
358 //!
359 //! \param ui32Interrupt specifies the interrupt to be queried.
360 //!
361 //! \return Returns:
362 //! - \c true : Specified interrupt is pending.
363 //! - \c false : Specified interrupt is not pending.
364 //
365 //*****************************************************************************
366 extern bool IntPendGet(uint32_t ui32Interrupt);
367
368 //*****************************************************************************
369 //
370 //! \brief Unpends an interrupt.
371 //!
372 //! The specified interrupt is unpended in the interrupt controller. This will
373 //! cause any previously generated interrupts that have not been handled yet
374 //! (due to higher priority interrupts or the interrupt no having been enabled
375 //! yet) to be discarded.
376 //!
377 //! \param ui32Interrupt specifies the interrupt to be unpended.
378 //!
379 //! \return None
380 //
381 //*****************************************************************************
382 extern void IntPendClear(uint32_t ui32Interrupt);
383
384 //*****************************************************************************
385 //
386 //! \brief Sets the priority masking level.
387 //!
388 //! This function sets the interrupt priority masking level so that all
389 //! interrupts at the specified or lesser priority level are masked. This
390 //! can be used to globally disable a set of interrupts with priority below
391 //! a predetermined threshold. A value of 0 disables priority
392 //! masking.
393 //!
394 //! Smaller numbers correspond to higher interrupt priorities. So for example
395 //! a priority level mask of 4 will allow interrupts of priority level 0-3,
396 //! and interrupts with a numerical priority of 4 and greater will be blocked.
397 //!
398 //! The hardware priority mechanism will only look at the upper N bits of the
399 //! priority level (where N is 3 for the CC26xx family), so any
400 //! prioritization must be performed in those bits.
401 //!
402 //! \param ui32PriorityMask is the priority level that will be masked.
403 //!
404 //! \return None.
405 //
406 //*****************************************************************************
407 __STATIC_INLINE void
IntPriorityMaskSet(uint32_t ui32PriorityMask)408 IntPriorityMaskSet(uint32_t ui32PriorityMask)
409 {
410 CPUbasepriSet(ui32PriorityMask);
411 }
412
413 //*****************************************************************************
414 //
415 //! \brief Gets the priority masking level.
416 //!
417 //! This function gets the current setting of the interrupt priority masking
418 //! level. The value returned is the priority level such that all interrupts
419 //! of that and lesser priority are masked. A value of 0 means that priority
420 //! masking is disabled.
421 //!
422 //! Smaller numbers correspond to higher interrupt priorities. So for example
423 //! a priority level mask of 4 will allow interrupts of priority level 0-3,
424 //! and interrupts with a numerical priority of 4 and greater will be blocked.
425 //!
426 //! The hardware priority mechanism will only look at the upper N bits of the
427 //! priority level (where N is 3 for the CC26xx family), so any
428 //! prioritization must be performed in those bits.
429 //!
430 //! \return Returns the value of the interrupt priority level mask.
431 //
432 //*****************************************************************************
433 __STATIC_INLINE uint32_t
IntPriorityMaskGet(void)434 IntPriorityMaskGet(void)
435 {
436 return(CPUbasepriGet());
437 }
438
439 //*****************************************************************************
440 //
441 // Support for DriverLib in ROM:
442 // Redirect to implementation in ROM when available.
443 //
444 //*****************************************************************************
445 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
446 #include <driverlib/rom.h>
447 #ifdef ROM_IntRegister
448 #undef IntRegister
449 #define IntRegister ROM_IntRegister
450 #endif
451 #ifdef ROM_IntUnregister
452 #undef IntUnregister
453 #define IntUnregister ROM_IntUnregister
454 #endif
455 #ifdef ROM_IntPriorityGroupingSet
456 #undef IntPriorityGroupingSet
457 #define IntPriorityGroupingSet ROM_IntPriorityGroupingSet
458 #endif
459 #ifdef ROM_IntPriorityGroupingGet
460 #undef IntPriorityGroupingGet
461 #define IntPriorityGroupingGet ROM_IntPriorityGroupingGet
462 #endif
463 #ifdef ROM_IntPrioritySet
464 #undef IntPrioritySet
465 #define IntPrioritySet ROM_IntPrioritySet
466 #endif
467 #ifdef ROM_IntPriorityGet
468 #undef IntPriorityGet
469 #define IntPriorityGet ROM_IntPriorityGet
470 #endif
471 #ifdef ROM_IntEnable
472 #undef IntEnable
473 #define IntEnable ROM_IntEnable
474 #endif
475 #ifdef ROM_IntDisable
476 #undef IntDisable
477 #define IntDisable ROM_IntDisable
478 #endif
479 #ifdef ROM_IntPendSet
480 #undef IntPendSet
481 #define IntPendSet ROM_IntPendSet
482 #endif
483 #ifdef ROM_IntPendGet
484 #undef IntPendGet
485 #define IntPendGet ROM_IntPendGet
486 #endif
487 #ifdef ROM_IntPendClear
488 #undef IntPendClear
489 #define IntPendClear ROM_IntPendClear
490 #endif
491 #endif
492
493 //*****************************************************************************
494 //
495 // Mark the end of the C bindings section for C++ compilers.
496 //
497 //*****************************************************************************
498 #ifdef __cplusplus
499 }
500 #endif
501
502 #endif // __INTERRUPT_H__
503
504 //*****************************************************************************
505 //
506 //! Close the Doxygen group.
507 //! @}
508 //! @}
509 //
510 //*****************************************************************************
511