CC26xx Driver Library |

- Main Page
- Related Pages
- CC26xx APIs
- Register Descriptions
- Online Resources

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
interrupt.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: interrupt.c
3 * Revised: 2015-01-13 16:59:55 +0100 (ti, 13 jan 2015)
4 * Revision: 42365
5 *
6 * Description: Driver 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 #include <driverlib/interrupt.h>
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #ifndef DRIVERLIB_GENERATE_ROM
48 #undef IntRegister
49 #define IntRegister NOROM_IntRegister
50 #undef IntUnregister
51 #define IntUnregister NOROM_IntUnregister
52 #undef IntPriorityGroupingSet
53 #define IntPriorityGroupingSet NOROM_IntPriorityGroupingSet
54 #undef IntPriorityGroupingGet
55 #define IntPriorityGroupingGet NOROM_IntPriorityGroupingGet
56 #undef IntPrioritySet
57 #define IntPrioritySet NOROM_IntPrioritySet
58 #undef IntPriorityGet
59 #define IntPriorityGet NOROM_IntPriorityGet
60 #undef IntEnable
61 #define IntEnable NOROM_IntEnable
62 #undef IntDisable
63 #define IntDisable NOROM_IntDisable
64 #undef IntPendSet
65 #define IntPendSet NOROM_IntPendSet
66 #undef IntPendGet
67 #define IntPendGet NOROM_IntPendGet
68 #undef IntPendClear
69 #define IntPendClear NOROM_IntPendClear
70 #endif
71
72 //*****************************************************************************
73 //
76 //
77 //*****************************************************************************
78 static const uint32_t g_pui32Priority[] =
79 {
80 NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
81 NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
82 NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
83 };
84
85 //*****************************************************************************
86 //
89 //
90 //*****************************************************************************
91 static const uint32_t g_pui32Regs[] =
92 {
93 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
94 NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
95 NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13
96 };
97
98 //*****************************************************************************
99 //
109 //
110 //*****************************************************************************
111 static void
112 IntDefaultHandler(void)
113 {
114 //
115 // Go into an infinite loop.
116 //
117 while(1)
118 {
119 }
120 }
121
122 //*****************************************************************************
123 //
124 // The processor vector table.
125 //
126 // This contains a list of the handlers for the various interrupt sources in
127 // the system. The layout of this list is defined by the hardware; assertion
128 // of an interrupt causes the processor to start executing directly at the
129 // address given in the corresponding location in this list.
130 //
131 // TBD : FIX Remember to remove "zero_init" from interrupt vector declaration
132 // TBD : How big must the interrupt table be?
133 //
134 //*****************************************************************************
135 #if defined(__IAR_SYSTEMS_ICC__)
136 #pragma data_alignment=256
137 static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ ".vtable_ram";
138 #elif defined(__TI_COMPILER_VERSION__) || defined(DOXYGEN)
139 #pragma DATA_ALIGN(g_pfnRAMVectors, 256)
140 #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable_ram")
141 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
142 #elif defined (rvmdk)
143 static __attribute__((section("vtable_ram")))
144 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(256),
145 zero_init));
146 #else
147 static __attribute__((section("vtable_ram")))
148 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(256)));
149 #endif
150
151 //*****************************************************************************
152 //
154 //
155 //*****************************************************************************
156 void
157 IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
158 {
159 uint32_t ui32Idx, ui32Value;
160
161 //
162 // Check the arguments.
163 //
164 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
165
166 //
167 // Make sure that the RAM vector table is correctly aligned.
168 //
169 ASSERT(((uint32_t)g_pfnRAMVectors & 0x000000ff) == 0);
170
171 //
172 // See if the RAM vector table has been initialized.
173 //
174 if(HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors)
175 {
176 //
177 // Copy the vector table from the beginning of FLASH to the RAM vector
178 // table.
179 //
180 ui32Value = HWREG(NVIC_VTABLE);
181 for(ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++)
182 {
183 g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) +
184 ui32Value);
185 }
186
187 //
188 // Point NVIC at the RAM vector table.
189 //
190 HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors;
191 }
192
193 //
194 // Save the interrupt handler.
195 //
196 g_pfnRAMVectors[ui32Interrupt] = pfnHandler;
197 }
198
199 //*****************************************************************************
200 //
202 //
203 //*****************************************************************************
204 void
205 IntUnregister(uint32_t ui32Interrupt)
206 {
207 //
208 // Check the arguments.
209 //
210 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
211
212 //
213 // Reset the interrupt handler.
214 //
215 g_pfnRAMVectors[ui32Interrupt] = IntDefaultHandler;
216 }
217
218 //*****************************************************************************
219 //
221 //
222 //*****************************************************************************
223 void
224 IntPriorityGroupingSet(uint32_t ui32Bits)
225 {
226 //
227 // Check the arguments.
228 //
229 ASSERT(ui32Bits < NUM_PRIORITY);
230
231 //
232 // Set the priority grouping.
233 //
234 HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits];
235 }
236
237 //*****************************************************************************
238 //
240 //
241 //*****************************************************************************
242 uint32_t
243 IntPriorityGroupingGet(void)
244 {
245 uint32_t ui32Loop, ui32Value;
246
247 //
248 // Read the priority grouping.
249 //
250 ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
251
252 //
253 // Loop through the priority grouping values.
254 //
255 for(ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++)
256 {
257 //
258 // Stop looping if this value matches.
259 //
260 if(ui32Value == g_pui32Priority[ui32Loop])
261 {
262 break;
263 }
264 }
265
266 //
267 // Return the number of priority bits.
268 //
269 return(ui32Loop);
270 }
271
272 //*****************************************************************************
273 //
275 //
276 //*****************************************************************************
277 void
278 IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
279 {
280 uint32_t ui32Temp;
281
282 //
283 // Check the arguments.
284 //
285 ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
286 ASSERT(ui8Priority <= INT_PRI_LEVEL7);
287
288 //
289 // Set the interrupt priority.
290 //
291 ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]);
292 ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3)));
293 ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3));
294 HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp;
295 }
296
297 //*****************************************************************************
298 //
300 //
301 //*****************************************************************************
302 int32_t
303 IntPriorityGet(uint32_t ui32Interrupt)
304 {
305 //
306 // Check the arguments.
307 //
308 ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
309
310 //
311 // Return the interrupt priority.
312 //
313 return((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >> (8 * (ui32Interrupt & 3))) &
314 0xFF);
315 }
316
317 //*****************************************************************************
318 //
320 //
321 //*****************************************************************************
322 void
323 IntEnable(uint32_t ui32Interrupt)
324 {
325 //
326 // Check the arguments.
327 //
328 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
329
330 //
331 // Determine the interrupt to enable.
332 //
333 if(ui32Interrupt == FAULT_MPU)
334 {
335 //
336 // Enable the MemManage interrupt.
337 //
338 HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
339 }
340 else if(ui32Interrupt == FAULT_BUS)
341 {
342 //
343 // Enable the bus fault interrupt.
344 //
345 HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
346 }
347 else if(ui32Interrupt == FAULT_USAGE)
348 {
349 //
350 // Enable the usage fault interrupt.
351 //
352 HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
353 }
354 else if(ui32Interrupt == FAULT_SYSTICK)
355 {
356 //
357 // Enable the System Tick interrupt.
358 //
359 HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
360 }
361 else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
362 {
363 //
364 // Enable the general interrupt.
365 //
366 HWREG(NVIC_EN0) = 1 << (ui32Interrupt - 16);
367 }
368 else if(ui32Interrupt >= 48)
369 {
370 //
371 // Enable the general interrupt.
372 //
373 HWREG(NVIC_EN1) = 1 << (ui32Interrupt - 48);
374 }
375 }
376
377 //*****************************************************************************
378 //
380 //
381 //*****************************************************************************
382 void
383 IntDisable(uint32_t ui32Interrupt)
384 {
385 //
386 // Check the arguments.
387 //
388 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
389
390 //
391 // Determine the interrupt to disable.
392 //
393 if(ui32Interrupt == FAULT_MPU)
394 {
395 //
396 // Disable the MemManage interrupt.
397 //
398 HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
399 }
400 else if(ui32Interrupt == FAULT_BUS)
401 {
402 //
403 // Disable the bus fault interrupt.
404 //
405 HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
406 }
407 else if(ui32Interrupt == FAULT_USAGE)
408 {
409 //
410 // Disable the usage fault interrupt.
411 //
412 HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
413 }
414 else if(ui32Interrupt == FAULT_SYSTICK)
415 {
416 //
417 // Disable the System Tick interrupt.
418 //
419 HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
420 }
421 else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
422 {
423 //
424 // Disable the general interrupt.
425 //
426 HWREG(NVIC_DIS0) = 1 << (ui32Interrupt - 16);
427 }
428 else if(ui32Interrupt >= 48)
429 {
430 //
431 // Disable the general interrupt.
432 //
433 HWREG(NVIC_DIS1) = 1 << (ui32Interrupt - 48);
434 }
435 }
436
437 //*****************************************************************************
438 //
440 //
441 //*****************************************************************************
442 void
443 IntPendSet(uint32_t ui32Interrupt)
444 {
445 //
446 // Check the arguments.
447 //
448 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
449
450 //
451 // Determine the interrupt to pend.
452 //
453 if(ui32Interrupt == FAULT_NMI)
454 {
455 //
456 // Pend the NMI interrupt.
457 //
458 HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
459 }
460 else if(ui32Interrupt == FAULT_PENDSV)
461 {
462 //
463 // Pend the PendSV interrupt.
464 //
465 HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
466 }
467 else if(ui32Interrupt == FAULT_SYSTICK)
468 {
469 //
470 // Pend the SysTick interrupt.
471 //
472 HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
473 }
474 else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
475 {
476 //
477 // Pend the general interrupt.
478 //
479 HWREG(NVIC_PEND0) = 1 << (ui32Interrupt - 16);
480 }
481 else if(ui32Interrupt >= 48)
482 {
483 //
484 // Pend the general interrupt.
485 //
486 HWREG(NVIC_PEND1) = 1 << (ui32Interrupt - 48);
487 }
488 }
489
490 //*****************************************************************************
491 //
493 //
494 //*****************************************************************************
495 bool
496 IntPendGet(uint32_t ui32Interrupt)
497 {
498 uint32_t ui32IntPending;
499
500 //
501 // Check the arguments.
502 //
503 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
504
505 //
506 // Assume no interrupts are pending.
507 //
508 ui32IntPending = 0;
509
510 //
511 // The lower 16 IRQ vectors are unsupported by this function
512 //
513 if (ui32Interrupt < 16)
514 {
515
516 return 0;
517 }
518
519 //
520 // Subtract lower 16 irq vectors
521 //
522 ui32Interrupt -= 16;
523
524 //
525 // Check if the interrupt is pending
526 //
527 ui32IntPending = HWREG(NVIC_PEND0 + (ui32Interrupt / 32));
528 ui32IntPending &= (1 << (ui32Interrupt & 31));
529
530 return ui32IntPending ? true : false;
531 }
532
533 //*****************************************************************************
534 //
536 //
537 //*****************************************************************************
538 void
539 IntPendClear(uint32_t ui32Interrupt)
540 {
541 //
542 // Check the arguments.
543 //
544 ASSERT(ui32Interrupt < NUM_INTERRUPTS);
545
546 //
547 // Determine the interrupt to unpend.
548 //
549 if(ui32Interrupt == FAULT_PENDSV)
550 {
551 //
552 // Unpend the PendSV interrupt.
553 //
554 HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
555 }
556 else if(ui32Interrupt == FAULT_SYSTICK)
557 {
558 //
559 // Unpend the SysTick interrupt.
560 //
561 HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
562 }
563 else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
564 {
565 //
566 // Unpend the general interrupt.
567 //
568 HWREG(NVIC_UNPEND0) = 1 << (ui32Interrupt - 16);
569 }
570 else if(ui32Interrupt >= 48)
571 {
572 //
573 // Unpend the general interrupt.
574 //
575 HWREG(NVIC_UNPEND1) = 1 << (ui32Interrupt - 48);
576 }
577 }
IntPriorityGet
int32_t IntPriorityGet(uint32_t ui32Interrupt)
Gets the priority of an interrupt.
Definition: interrupt.c:303
g_pfnRAMVectors
void(* g_pfnRAMVectors[NUM_INTERRUPTS])(void)
Definition: interrupt.c:141
IntPendClear
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:539
IntPriorityGroupingSet
void IntPriorityGroupingSet(uint32_t ui32Bits)
Sets the priority grouping of the interrupt controller.
Definition: interrupt.c:224
ASSERT
#define ASSERT(expr)
Definition: debug.h:65
INT_PRI_LEVEL7
#define INT_PRI_LEVEL7
Definition: interrupt.h:115
IntPriorityGroupingGet
uint32_t IntPriorityGroupingGet(void)
Gets the priority grouping of the interrupt controller.
Definition: interrupt.c:243
IntPendSet
void IntPendSet(uint32_t ui32Interrupt)
Pends an interrupt.
Definition: interrupt.c:443
interrupt.h
IntUnregister
void IntUnregister(uint32_t ui32Interrupt)
Unregisters the function to be called when an interrupt occurs.
Definition: interrupt.c:205
IntPrioritySet
void IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
Sets the priority of an interrupt.
Definition: interrupt.c:278
IntPendGet
bool IntPendGet(uint32_t ui32Interrupt)
Query whether an interrupt is pending.
Definition: interrupt.c:496
IntDisable
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt.
Definition: interrupt.c:383
IntRegister
void IntRegister(uint32_t ui32Interrupt, void(*pfnHandler)(void))
Registers a function to be called when an interrupt occurs.
Definition: interrupt.c:157
IntEnable
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt.
Definition: interrupt.c:323