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