CC26xx Driver Library
interrupt.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: interrupt.c
3 * Revised: 2016-06-30 09:21:03 +0200 (Thu, 30 Jun 2016)
4 * Revision: 46799
5 *
6 * Description: Driver for the NVIC Interrupt Controller.
7 *
8 * Copyright (c) 2015 - 2016, 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 #if !defined(DOXYGEN)
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 //
108 //
109 //*****************************************************************************
110 static void
112 {
113  //
114  // Go into an infinite loop.
115  //
116  while(1)
117  {
118  }
119 }
120 
121 //*****************************************************************************
122 //
123 // The processor vector table.
124 //
125 // This contains a list of the handlers for the various interrupt sources in
126 // the system. The layout of this list is defined by the hardware; assertion
127 // of an interrupt causes the processor to start executing directly at the
128 // address given in the corresponding location in this list.
129 //
130 //*****************************************************************************
131 #if defined(__IAR_SYSTEMS_ICC__)
132 #pragma data_alignment=256
133 static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ ".vtable_ram";
134 #elif defined(__TI_COMPILER_VERSION__) || defined(DOXYGEN)
135 #pragma DATA_ALIGN(g_pfnRAMVectors, 256)
136 #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable_ram")
137 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
138 #elif defined (__CC_ARM)
139 static __attribute__((section("vtable_ram")))
140 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(256)));
141 #else
142 static __attribute__((section("vtable_ram")))
143 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(256)));
144 #endif
145 
146 //*****************************************************************************
147 //
149 //
150 //*****************************************************************************
151 void
152 IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
153 {
154  uint32_t ui32Idx, ui32Value;
155 
156  //
157  // Check the arguments.
158  //
159  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
160 
161  //
162  // Make sure that the RAM vector table is correctly aligned.
163  //
164  ASSERT(((uint32_t)g_pfnRAMVectors & 0x000000ff) == 0);
165 
166  //
167  // See if the RAM vector table has been initialized.
168  //
169  if(HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors)
170  {
171  //
172  // Copy the vector table from the beginning of FLASH to the RAM vector
173  // table.
174  //
175  ui32Value = HWREG(NVIC_VTABLE);
176  for(ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++)
177  {
178  g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) +
179  ui32Value);
180  }
181 
182  //
183  // Point NVIC at the RAM vector table.
184  //
185  HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors;
186  }
187 
188  //
189  // Save the interrupt handler.
190  //
191  g_pfnRAMVectors[ui32Interrupt] = pfnHandler;
192 }
193 
194 //*****************************************************************************
195 //
197 //
198 //*****************************************************************************
199 void
200 IntUnregister(uint32_t ui32Interrupt)
201 {
202  //
203  // Check the arguments.
204  //
205  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
206 
207  //
208  // Reset the interrupt handler.
209  //
210  g_pfnRAMVectors[ui32Interrupt] = IntDefaultHandler;
211 }
212 
213 //*****************************************************************************
214 //
216 //
217 //*****************************************************************************
218 void
219 IntPriorityGroupingSet(uint32_t ui32Bits)
220 {
221  //
222  // Check the arguments.
223  //
224  ASSERT(ui32Bits < NUM_PRIORITY);
225 
226  //
227  // Set the priority grouping.
228  //
229  HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits];
230 }
231 
232 //*****************************************************************************
233 //
235 //
236 //*****************************************************************************
237 uint32_t
239 {
240  uint32_t ui32Loop, ui32Value;
241 
242  //
243  // Read the priority grouping.
244  //
245  ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
246 
247  //
248  // Loop through the priority grouping values.
249  //
250  for(ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++)
251  {
252  //
253  // Stop looping if this value matches.
254  //
255  if(ui32Value == g_pui32Priority[ui32Loop])
256  {
257  break;
258  }
259  }
260 
261  //
262  // Return the number of priority bits.
263  //
264  return(ui32Loop);
265 }
266 
267 //*****************************************************************************
268 //
270 //
271 //*****************************************************************************
272 void
273 IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
274 {
275  uint32_t ui32Temp;
276 
277  //
278  // Check the arguments.
279  //
280  ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
281  ASSERT(ui8Priority <= INT_PRI_LEVEL7);
282 
283  //
284  // Set the interrupt priority.
285  //
286  ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]);
287  ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3)));
288  ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3));
289  HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp;
290 }
291 
292 //*****************************************************************************
293 //
295 //
296 //*****************************************************************************
297 int32_t
298 IntPriorityGet(uint32_t ui32Interrupt)
299 {
300  //
301  // Check the arguments.
302  //
303  ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
304 
305  //
306  // Return the interrupt priority.
307  //
308  return((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >> (8 * (ui32Interrupt & 3))) &
309  0xFF);
310 }
311 
312 //*****************************************************************************
313 //
315 //
316 //*****************************************************************************
317 void
318 IntEnable(uint32_t ui32Interrupt)
319 {
320  //
321  // Check the arguments.
322  //
323  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
324 
325  //
326  // Determine the interrupt to enable.
327  //
328  if(ui32Interrupt == INT_MEMMANAGE_FAULT)
329  {
330  //
331  // Enable the MemManage interrupt.
332  //
333  HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
334  }
335  else if(ui32Interrupt == INT_BUS_FAULT)
336  {
337  //
338  // Enable the bus fault interrupt.
339  //
340  HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
341  }
342  else if(ui32Interrupt == INT_USAGE_FAULT)
343  {
344  //
345  // Enable the usage fault interrupt.
346  //
347  HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
348  }
349  else if(ui32Interrupt == INT_SYSTICK)
350  {
351  //
352  // Enable the System Tick interrupt.
353  //
354  HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
355  }
356  else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
357  {
358  //
359  // Enable the general interrupt.
360  //
361  HWREG(NVIC_EN0) = 1 << (ui32Interrupt - 16);
362  }
363  else if(ui32Interrupt >= 48)
364  {
365  //
366  // Enable the general interrupt.
367  //
368  HWREG(NVIC_EN1) = 1 << (ui32Interrupt - 48);
369  }
370 }
371 
372 //*****************************************************************************
373 //
375 //
376 //*****************************************************************************
377 void
378 IntDisable(uint32_t ui32Interrupt)
379 {
380  //
381  // Check the arguments.
382  //
383  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
384 
385  //
386  // Determine the interrupt to disable.
387  //
388  if(ui32Interrupt == INT_MEMMANAGE_FAULT)
389  {
390  //
391  // Disable the MemManage interrupt.
392  //
393  HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
394  }
395  else if(ui32Interrupt == INT_BUS_FAULT)
396  {
397  //
398  // Disable the bus fault interrupt.
399  //
400  HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
401  }
402  else if(ui32Interrupt == INT_USAGE_FAULT)
403  {
404  //
405  // Disable the usage fault interrupt.
406  //
407  HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
408  }
409  else if(ui32Interrupt == INT_SYSTICK)
410  {
411  //
412  // Disable the System Tick interrupt.
413  //
414  HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
415  }
416  else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
417  {
418  //
419  // Disable the general interrupt.
420  //
421  HWREG(NVIC_DIS0) = 1 << (ui32Interrupt - 16);
422  }
423  else if(ui32Interrupt >= 48)
424  {
425  //
426  // Disable the general interrupt.
427  //
428  HWREG(NVIC_DIS1) = 1 << (ui32Interrupt - 48);
429  }
430 }
431 
432 //*****************************************************************************
433 //
435 //
436 //*****************************************************************************
437 void
438 IntPendSet(uint32_t ui32Interrupt)
439 {
440  //
441  // Check the arguments.
442  //
443  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
444 
445  //
446  // Determine the interrupt to pend.
447  //
448  if(ui32Interrupt == INT_NMI_FAULT)
449  {
450  //
451  // Pend the NMI interrupt.
452  //
453  HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
454  }
455  else if(ui32Interrupt == INT_PENDSV)
456  {
457  //
458  // Pend the PendSV interrupt.
459  //
460  HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
461  }
462  else if(ui32Interrupt == INT_SYSTICK)
463  {
464  //
465  // Pend the SysTick interrupt.
466  //
467  HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
468  }
469  else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
470  {
471  //
472  // Pend the general interrupt.
473  //
474  HWREG(NVIC_PEND0) = 1 << (ui32Interrupt - 16);
475  }
476  else if(ui32Interrupt >= 48)
477  {
478  //
479  // Pend the general interrupt.
480  //
481  HWREG(NVIC_PEND1) = 1 << (ui32Interrupt - 48);
482  }
483 }
484 
485 //*****************************************************************************
486 //
488 //
489 //*****************************************************************************
490 bool
491 IntPendGet(uint32_t ui32Interrupt)
492 {
493  uint32_t ui32IntPending;
494 
495  //
496  // Check the arguments.
497  //
498  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
499 
500  //
501  // Assume no interrupts are pending.
502  //
503  ui32IntPending = 0;
504 
505  //
506  // The lower 16 IRQ vectors are unsupported by this function
507  //
508  if (ui32Interrupt < 16)
509  {
510 
511  return 0;
512  }
513 
514  //
515  // Subtract lower 16 irq vectors
516  //
517  ui32Interrupt -= 16;
518 
519  //
520  // Check if the interrupt is pending
521  //
522  ui32IntPending = HWREG(NVIC_PEND0 + (ui32Interrupt / 32));
523  ui32IntPending &= (1 << (ui32Interrupt & 31));
524 
525  return ui32IntPending ? true : false;
526 }
527 
528 //*****************************************************************************
529 //
531 //
532 //*****************************************************************************
533 void
534 IntPendClear(uint32_t ui32Interrupt)
535 {
536  //
537  // Check the arguments.
538  //
539  ASSERT(ui32Interrupt < NUM_INTERRUPTS);
540 
541  //
542  // Determine the interrupt to unpend.
543  //
544  if(ui32Interrupt == INT_PENDSV)
545  {
546  //
547  // Unpend the PendSV interrupt.
548  //
549  HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
550  }
551  else if(ui32Interrupt == INT_SYSTICK)
552  {
553  //
554  // Unpend the SysTick interrupt.
555  //
556  HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
557  }
558  else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
559  {
560  //
561  // Unpend the general interrupt.
562  //
563  HWREG(NVIC_UNPEND0) = 1 << (ui32Interrupt - 16);
564  }
565  else if(ui32Interrupt >= 48)
566  {
567  //
568  // Unpend the general interrupt.
569  //
570  HWREG(NVIC_UNPEND1) = 1 << (ui32Interrupt - 48);
571  }
572 }
int32_t IntPriorityGet(uint32_t ui32Interrupt)
Gets the priority of an interrupt.
Definition: interrupt.c:298
void(* g_pfnRAMVectors[NUM_INTERRUPTS])(void)
Definition: interrupt.c:137
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:534
static const uint32_t g_pui32Regs[]
Definition: interrupt.c:91
void IntPriorityGroupingSet(uint32_t ui32Bits)
Sets the priority grouping of the interrupt controller.
Definition: interrupt.c:219
#define INT_PRI_LEVEL7
Definition: interrupt.h:115
uint32_t IntPriorityGroupingGet(void)
Gets the priority grouping of the interrupt controller.
Definition: interrupt.c:238
void IntPendSet(uint32_t ui32Interrupt)
Pends an interrupt.
Definition: interrupt.c:438
#define ASSERT(expr)
Definition: debug.h:74
void IntUnregister(uint32_t ui32Interrupt)
Unregisters the function to be called when an interrupt occurs.
Definition: interrupt.c:200
void IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
Sets the priority of an interrupt.
Definition: interrupt.c:273
static void IntDefaultHandler(void)
The default interrupt handler.
Definition: interrupt.c:111
bool IntPendGet(uint32_t ui32Interrupt)
Query whether an interrupt is pending.
Definition: interrupt.c:491
static const uint32_t g_pui32Priority[]
Definition: interrupt.c:78
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt.
Definition: interrupt.c:378
void IntRegister(uint32_t ui32Interrupt, void(*pfnHandler)(void))
Registers a function to be called when an interrupt occurs.
Definition: interrupt.c:152
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt.
Definition: interrupt.c:318