1 //*****************************************************************************
2 //
3 // interrupt.c - Driver for the NVIC Interrupt Controller.
4 //
5 // Copyright (c) 2005-2011 Texas Instruments Incorporated.  All rights reserved.
6 // Software License Agreement
7 //
8 // Texas Instruments (TI) is supplying this software for use solely and
9 // exclusively on TI's microcontroller products. The software is owned by
10 // TI and/or its suppliers, and is protected under applicable copyright
11 // laws. You may not combine this software with "viral" open-source
12 // software in order to form a larger program.
13 //
14 // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
15 // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
16 // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
18 // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
19 // DAMAGES, FOR ANY REASON WHATSOEVER.
20 //
21 // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
22 //
23 //*****************************************************************************
24 
25 //*****************************************************************************
26 //
27 //! \addtogroup interrupt_api
28 //! @{
29 //
30 //*****************************************************************************
31 
32 #include "inc/hw_ints.h"
33 #include "inc/hw_nvic.h"
34 #include "inc/hw_types.h"
35 #include "driverlib/cpu.h"
36 #include "driverlib/debug.h"
37 #include "driverlib/interrupt.h"
38 
39 //*****************************************************************************
40 //
41 // This is a mapping between priority grouping encodings and the number of
42 // preemption priority bits.
43 //
44 //*****************************************************************************
45 static const unsigned long g_pulPriority[] =
46 {
47     NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
48     NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
49     NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
50 };
51 
52 //*****************************************************************************
53 //
54 // This is a mapping between interrupt number and the register that contains
55 // the priority encoding for that interrupt.
56 //
57 //*****************************************************************************
58 static const unsigned long g_pulRegs[] =
59 {
60     0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
61     NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
62     NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13,
63     NVIC_PRI14, NVIC_PRI15, NVIC_PRI16, NVIC_PRI17, NVIC_PRI18, NVIC_PRI19,
64     NVIC_PRI20, NVIC_PRI21, NVIC_PRI22, NVIC_PRI23, NVIC_PRI24, NVIC_PRI25,
65     NVIC_PRI26, NVIC_PRI27, NVIC_PRI28, NVIC_PRI29, NVIC_PRI30, NVIC_PRI31,
66     NVIC_PRI32
67 };
68 
69 //*****************************************************************************
70 //
71 // This is a mapping between interrupt number (for the peripheral interrupts
72 // only) and the register that contains the interrupt enable for that
73 // interrupt.
74 //
75 //*****************************************************************************
76 static const unsigned long g_pulEnRegs[] =
77 {
78     NVIC_EN0, NVIC_EN1, NVIC_EN2, NVIC_EN3, NVIC_EN4
79 };
80 
81 //*****************************************************************************
82 //
83 // This is a mapping between interrupt number (for the peripheral interrupts
84 // only) and the register that contains the interrupt disable for that
85 // interrupt.
86 //
87 //*****************************************************************************
88 static const unsigned long g_pulDisRegs[] =
89 {
90     NVIC_DIS0, NVIC_DIS1, NVIC_DIS2, NVIC_DIS3, NVIC_DIS4
91 };
92 
93 //*****************************************************************************
94 //
95 // This is a mapping between interrupt number (for the peripheral interrupts
96 // only) and the register that contains the interrupt pend for that interrupt.
97 //
98 //*****************************************************************************
99 static const unsigned long g_pulPendRegs[] =
100 {
101     NVIC_PEND0, NVIC_PEND1, NVIC_PEND2, NVIC_PEND3, NVIC_PEND4
102 };
103 
104 //*****************************************************************************
105 //
106 // This is a mapping between interrupt number (for the peripheral interrupts
107 // only) and the register that contains the interrupt unpend for that
108 // interrupt.
109 //
110 //*****************************************************************************
111 static const unsigned long g_pulUnpendRegs[] =
112 {
113     NVIC_UNPEND0, NVIC_UNPEND1, NVIC_UNPEND2, NVIC_UNPEND3, NVIC_UNPEND4
114 };
115 
116 //*****************************************************************************
117 //
118 //! \internal
119 //! The default interrupt handler.
120 //!
121 //! This is the default interrupt handler for all interrupts.  It simply loops
122 //! forever so that the system state is preserved for observation by a
123 //! debugger.  Since interrupts should be disabled before unregistering the
124 //! corresponding handler, this should never be called.
125 //!
126 //! \return None.
127 //
128 //*****************************************************************************
129 static void
IntDefaultHandler(void)130 IntDefaultHandler(void)
131 {
132     //
133     // Go into an infinite loop.
134     //
135     while(1)
136     {
137     }
138 }
139 
140 //*****************************************************************************
141 //
142 // The processor vector table.
143 //
144 // This contains a list of the handlers for the various interrupt sources in
145 // the system.  The layout of this list is defined by the hardware; assertion
146 // of an interrupt causes the processor to start executing directly at the
147 // address given in the corresponding location in this list.
148 //
149 //*****************************************************************************
150 #if defined(ewarm)
151 #pragma data_alignment=1024
152 static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE";
153 #elif defined(sourcerygxx)
154 static __attribute__((section(".cs3.region-head.ram")))
155 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__ ((aligned(1024)));
156 #elif defined(ccs) || defined(DOXYGEN)
157 #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
158 #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
159 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
160 #else
161 static __attribute__((section("vtable")))
162 void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__ ((aligned(1024)));
163 #endif
164 
165 //*****************************************************************************
166 //
167 //! Enables the processor interrupt.
168 //!
169 //! This function allows the processor to respond to interrupts.  This function
170 //! does not affect the set of interrupts enabled in the interrupt controller;
171 //! it just gates the single interrupt from the controller to the processor.
172 //!
173 //! \note Previously, this function had no return value.  As such, it was
174 //! possible to include <tt>interrupt.h</tt> and call this function without
175 //! having included <tt>hw_types.h</tt>.  Now that the return is a
176 //! <tt>tBoolean</tt>, a compiler error occurs in this case.  The solution
177 //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
178 //!
179 //! \return Returns \b true if interrupts were disabled when the function was
180 //! called or \b false if they were initially enabled.
181 //
182 //*****************************************************************************
183 tBoolean
IntMasterEnable(void)184 IntMasterEnable(void)
185 {
186     //
187     // Enable processor interrupts.
188     //
189     return(CPUcpsie());
190 }
191 
192 //*****************************************************************************
193 //
194 //! Disables the processor interrupt.
195 //!
196 //! This function prevents the processor from receiving interrupts.  This
197 //! function does not affect the set of interrupts enabled in the interrupt
198 //! controller; it just gates the single interrupt from the controller to the
199 //! processor.
200 //!
201 //! \note Previously, this function had no return value.  As such, it was
202 //! possible to include <tt>interrupt.h</tt> and call this function without
203 //! having included <tt>hw_types.h</tt>.  Now that the return is a
204 //! <tt>tBoolean</tt>, a compiler error occurs in this case.  The solution
205 //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
206 //!
207 //! \return Returns \b true if interrupts were already disabled when the
208 //! function was called or \b false if they were initially enabled.
209 //
210 //*****************************************************************************
211 tBoolean
IntMasterDisable(void)212 IntMasterDisable(void)
213 {
214     //
215     // Disable processor interrupts.
216     //
217     return(CPUcpsid());
218 }
219 
220 //*****************************************************************************
221 //
222 //! Registers a function to be called when an interrupt occurs.
223 //!
224 //! \param ulInterrupt specifies the interrupt in question.
225 //! \param pfnHandler is a pointer to the function to be called.
226 //!
227 //! This function is used to specify the handler function to be called when the
228 //! given interrupt is asserted to the processor.  When the interrupt occurs,
229 //! if it is enabled (via IntEnable()), the handler function is called in
230 //! interrupt context.  Because the handler function can preempt other code,
231 //! care must be taken to protect memory or peripherals that are accessed by
232 //! the handler and other non-handler code.
233 //!
234 //! \note The use of this function (directly or indirectly via a peripheral
235 //! driver interrupt register function) moves the interrupt vector table from
236 //! flash to SRAM.  Therefore, care must be taken when linking the application
237 //! to ensure that the SRAM vector table is located at the beginning of SRAM;
238 //! otherwise the NVIC does not look in the correct portion of memory for the
239 //! vector table (it requires the vector table be on a 1 kB memory alignment).
240 //! Normally, the SRAM vector table is so placed via the use of linker scripts.
241 //! See the discussion of compile-time versus run-time interrupt handler
242 //! registration in the introduction to this chapter.
243 //!
244 //! \return None.
245 //
246 //*****************************************************************************
247 void
IntRegister(unsigned long ulInterrupt,void (* pfnHandler)(void))248 IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void))
249 {
250     unsigned long ulIdx, ulValue;
251 
252     //
253     // Check the arguments.
254     //
255     ASSERT(ulInterrupt < NUM_INTERRUPTS);
256 
257     //
258     // Make sure that the RAM vector table is correctly aligned.
259     //
260     ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0);
261 
262     //
263     // See if the RAM vector table has been initialized.
264     //
265     if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors)
266     {
267         //
268         // Copy the vector table from the beginning of FLASH to the RAM vector
269         // table.
270         //
271         ulValue = HWREG(NVIC_VTABLE);
272         for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++)
273         {
274             g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG((ulIdx * 4) +
275                                                      ulValue);
276         }
277 
278         //
279         // Point the NVIC at the RAM vector table.
280         //
281         HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors;
282     }
283 
284     //
285     // Save the interrupt handler.
286     //
287     g_pfnRAMVectors[ulInterrupt] = pfnHandler;
288 }
289 
290 //*****************************************************************************
291 //
292 //! Unregisters the function to be called when an interrupt occurs.
293 //!
294 //! \param ulInterrupt specifies the interrupt in question.
295 //!
296 //! This function is used to indicate that no handler should be called when the
297 //! given interrupt is asserted to the processor.  The interrupt source is
298 //! automatically disabled (via IntDisable()) if necessary.
299 //!
300 //! \sa IntRegister() for important information about registering interrupt
301 //! handlers.
302 //!
303 //! \return None.
304 //
305 //*****************************************************************************
306 void
IntUnregister(unsigned long ulInterrupt)307 IntUnregister(unsigned long ulInterrupt)
308 {
309     //
310     // Check the arguments.
311     //
312     ASSERT(ulInterrupt < NUM_INTERRUPTS);
313 
314     //
315     // Reset the interrupt handler.
316     //
317     g_pfnRAMVectors[ulInterrupt] = IntDefaultHandler;
318 }
319 
320 //*****************************************************************************
321 //
322 //! Sets the priority grouping of the interrupt controller.
323 //!
324 //! \param ulBits specifies the number of bits of preemptable priority.
325 //!
326 //! This function specifies the split between preemptable priority levels and
327 //! subpriority levels in the interrupt priority specification.  The range of
328 //! the grouping values are dependent upon the hardware implementation; on
329 //! the Stellaris family, three bits are available for hardware interrupt
330 //! prioritization and therefore priority grouping values of three through
331 //! seven have the same effect.
332 //!
333 //! \return None.
334 //
335 //*****************************************************************************
336 void
IntPriorityGroupingSet(unsigned long ulBits)337 IntPriorityGroupingSet(unsigned long ulBits)
338 {
339     //
340     // Check the arguments.
341     //
342     ASSERT(ulBits < NUM_PRIORITY);
343 
344     //
345     // Set the priority grouping.
346     //
347     HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pulPriority[ulBits];
348 }
349 
350 //*****************************************************************************
351 //
352 //! Gets the priority grouping of the interrupt controller.
353 //!
354 //! This function returns the split between preemptable priority levels and
355 //! subpriority levels in the interrupt priority specification.
356 //!
357 //! \return The number of bits of preemptable priority.
358 //
359 //*****************************************************************************
360 unsigned long
IntPriorityGroupingGet(void)361 IntPriorityGroupingGet(void)
362 {
363     unsigned long ulLoop, ulValue;
364 
365     //
366     // Read the priority grouping.
367     //
368     ulValue = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
369 
370     //
371     // Loop through the priority grouping values.
372     //
373     for(ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++)
374     {
375         //
376         // Stop looping if this value matches.
377         //
378         if(ulValue == g_pulPriority[ulLoop])
379         {
380             break;
381         }
382     }
383 
384     //
385     // Return the number of priority bits.
386     //
387     return(ulLoop);
388 }
389 
390 //*****************************************************************************
391 //
392 //! Sets the priority of an interrupt.
393 //!
394 //! \param ulInterrupt specifies the interrupt in question.
395 //! \param ucPriority specifies the priority of the interrupt.
396 //!
397 //! This function is used to set the priority of an interrupt.  When multiple
398 //! interrupts are asserted simultaneously, the ones with the highest priority
399 //! are processed before the lower priority interrupts.  Smaller numbers
400 //! correspond to higher interrupt priorities; priority 0 is the highest
401 //! interrupt priority.
402 //!
403 //! The hardware priority mechanism only looks at the upper N bits of the
404 //! priority level (where N is 3 for the Stellaris family), so any
405 //! prioritization must be performed in those bits.  The remaining bits can be
406 //! used to sub-prioritize the interrupt sources, and may be used by the
407 //! hardware priority mechanism on a future part.  This arrangement allows
408 //! priorities to migrate to different NVIC implementations without changing
409 //! the gross prioritization of the interrupts.
410 //!
411 //! \return None.
412 //
413 //*****************************************************************************
414 void
IntPrioritySet(unsigned long ulInterrupt,unsigned char ucPriority)415 IntPrioritySet(unsigned long ulInterrupt, unsigned char ucPriority)
416 {
417     unsigned long ulTemp;
418 
419     //
420     // Check the arguments.
421     //
422     ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
423 
424     //
425     // Set the interrupt priority.
426     //
427     ulTemp = HWREG(g_pulRegs[ulInterrupt >> 2]);
428     ulTemp &= ~(0xFF << (8 * (ulInterrupt & 3)));
429     ulTemp |= ucPriority << (8 * (ulInterrupt & 3));
430     HWREG(g_pulRegs[ulInterrupt >> 2]) = ulTemp;
431 }
432 
433 //*****************************************************************************
434 //
435 //! Gets the priority of an interrupt.
436 //!
437 //! \param ulInterrupt specifies the interrupt in question.
438 //!
439 //! This function gets the priority of an interrupt.  See IntPrioritySet() for
440 //! a definition of the priority value.
441 //!
442 //! \return Returns the interrupt priority, or -1 if an invalid interrupt was
443 //! specified.
444 //
445 //*****************************************************************************
446 long
IntPriorityGet(unsigned long ulInterrupt)447 IntPriorityGet(unsigned long ulInterrupt)
448 {
449     //
450     // Check the arguments.
451     //
452     ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
453 
454     //
455     // Return the interrupt priority.
456     //
457     return((HWREG(g_pulRegs[ulInterrupt >> 2]) >> (8 * (ulInterrupt & 3))) &
458            0xFF);
459 }
460 
461 //*****************************************************************************
462 //
463 //! Enables an interrupt.
464 //!
465 //! \param ulInterrupt specifies the interrupt to be enabled.
466 //!
467 //! The specified interrupt is enabled in the interrupt controller.  Other
468 //! enables for the interrupt (such as at the peripheral level) are unaffected
469 //! by this function.
470 //!
471 //! \return None.
472 //
473 //*****************************************************************************
474 void
IntEnable(unsigned long ulInterrupt)475 IntEnable(unsigned long ulInterrupt)
476 {
477     //
478     // Check the arguments.
479     //
480     ASSERT(ulInterrupt < NUM_INTERRUPTS);
481 
482     //
483     // Determine the interrupt to enable.
484     //
485     if(ulInterrupt == FAULT_MPU)
486     {
487         //
488         // Enable the MemManage interrupt.
489         //
490         HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
491     }
492     else if(ulInterrupt == FAULT_BUS)
493     {
494         //
495         // Enable the bus fault interrupt.
496         //
497         HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
498     }
499     else if(ulInterrupt == FAULT_USAGE)
500     {
501         //
502         // Enable the usage fault interrupt.
503         //
504         HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
505     }
506     else if(ulInterrupt == FAULT_SYSTICK)
507     {
508         //
509         // Enable the System Tick interrupt.
510         //
511         HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
512     }
513     else if(ulInterrupt >= 16)
514     {
515         //
516         // Enable the general interrupt.
517         //
518         HWREG(g_pulEnRegs[(ulInterrupt - 16) / 32]) =
519             1 << ((ulInterrupt - 16) & 31);
520     }
521 }
522 
523 //*****************************************************************************
524 //
525 //! Disables an interrupt.
526 //!
527 //! \param ulInterrupt specifies the interrupt to be disabled.
528 //!
529 //! The specified interrupt is disabled in the interrupt controller.  Other
530 //! enables for the interrupt (such as at the peripheral level) are unaffected
531 //! by this function.
532 //!
533 //! \return None.
534 //
535 //*****************************************************************************
536 void
IntDisable(unsigned long ulInterrupt)537 IntDisable(unsigned long ulInterrupt)
538 {
539     //
540     // Check the arguments.
541     //
542     ASSERT(ulInterrupt < NUM_INTERRUPTS);
543 
544     //
545     // Determine the interrupt to disable.
546     //
547     if(ulInterrupt == FAULT_MPU)
548     {
549         //
550         // Disable the MemManage interrupt.
551         //
552         HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
553     }
554     else if(ulInterrupt == FAULT_BUS)
555     {
556         //
557         // Disable the bus fault interrupt.
558         //
559         HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
560     }
561     else if(ulInterrupt == FAULT_USAGE)
562     {
563         //
564         // Disable the usage fault interrupt.
565         //
566         HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
567     }
568     else if(ulInterrupt == FAULT_SYSTICK)
569     {
570         //
571         // Disable the System Tick interrupt.
572         //
573         HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
574     }
575     else if(ulInterrupt >= 16)
576     {
577         //
578         // Disable the general interrupt.
579         //
580         HWREG(g_pulDisRegs[(ulInterrupt - 16) / 32]) =
581             1 << ((ulInterrupt - 16) & 31);
582     }
583 }
584 
585 //*****************************************************************************
586 //
587 //! Pends an interrupt.
588 //!
589 //! \param ulInterrupt specifies the interrupt to be pended.
590 //!
591 //! The specified interrupt is pended in the interrupt controller.  Pending an
592 //! interrupt causes the interrupt controller to execute the corresponding
593 //! interrupt handler at the next available time, based on the current
594 //! interrupt state priorities. For example, if called by a higher priority
595 //! interrupt handler, the specified interrupt handler is not called until
596 //! after the current interrupt handler has completed execution.  The interrupt
597 //! must have been enabled for it to be called.
598 //!
599 //! \return None.
600 //
601 //*****************************************************************************
602 void
IntPendSet(unsigned long ulInterrupt)603 IntPendSet(unsigned long ulInterrupt)
604 {
605     //
606     // Check the arguments.
607     //
608     ASSERT(ulInterrupt < NUM_INTERRUPTS);
609 
610     //
611     // Determine the interrupt to pend.
612     //
613     if(ulInterrupt == FAULT_NMI)
614     {
615         //
616         // Pend the NMI interrupt.
617         //
618         HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
619     }
620     else if(ulInterrupt == FAULT_PENDSV)
621     {
622         //
623         // Pend the PendSV interrupt.
624         //
625         HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
626     }
627     else if(ulInterrupt == FAULT_SYSTICK)
628     {
629         //
630         // Pend the SysTick interrupt.
631         //
632         HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
633     }
634     else if(ulInterrupt >= 16)
635     {
636         //
637         // Pend the general interrupt.
638         //
639         HWREG(g_pulPendRegs[(ulInterrupt - 16) / 32]) =
640             1 << ((ulInterrupt - 16) & 31);
641     }
642 }
643 
644 //*****************************************************************************
645 //
646 //! Unpends an interrupt.
647 //!
648 //! \param ulInterrupt specifies the interrupt to be unpended.
649 //!
650 //! The specified interrupt is unpended in the interrupt controller.  Unpending
651 //! an interrupt causes any previously generated interrupts that have not been
652 //! handled yet (due to higher priority interrupts or the interrupt not having
653 //! been enabled yet) to be discarded.
654 //!
655 //! \return None.
656 //
657 //*****************************************************************************
658 void
IntPendClear(unsigned long ulInterrupt)659 IntPendClear(unsigned long ulInterrupt)
660 {
661     //
662     // Check the arguments.
663     //
664     ASSERT(ulInterrupt < NUM_INTERRUPTS);
665 
666     //
667     // Determine the interrupt to unpend.
668     //
669     if(ulInterrupt == FAULT_PENDSV)
670     {
671         //
672         // Unpend the PendSV interrupt.
673         //
674         HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
675     }
676     else if(ulInterrupt == FAULT_SYSTICK)
677     {
678         //
679         // Unpend the SysTick interrupt.
680         //
681         HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
682     }
683     else if(ulInterrupt >= 16)
684     {
685         //
686         // Unpend the general interrupt.
687         //
688         HWREG(g_pulUnpendRegs[(ulInterrupt - 16) / 32]) =
689             1 << ((ulInterrupt - 16) & 31);
690     }
691 }
692 
693 //*****************************************************************************
694 //
695 //! Sets the priority masking level
696 //!
697 //! \param ulPriorityMask is the priority level that is masked.
698 //!
699 //! This function sets the interrupt priority masking level so that all
700 //! interrupts at the specified or lesser priority level are masked.  Masking
701 //! interrupts can be used to globally disable a set of interrupts with
702 //! priority below a predetermined threshold.  A value of 0 disables priority
703 //! masking.
704 //!
705 //! Smaller numbers correspond to higher interrupt priorities.  So for example
706 //! a priority level mask of 4 allows interrupts of priority level 0-3,
707 //! and interrupts with a numerical priority of 4 and greater are blocked.
708 //!
709 //! The hardware priority mechanism only looks at the upper N bits of the
710 //! priority level (where N is 3 for the Stellaris family), so any
711 //! prioritization must be performed in those bits.
712 //!
713 //! \return None.
714 //
715 //*****************************************************************************
716 void
IntPriorityMaskSet(unsigned long ulPriorityMask)717 IntPriorityMaskSet(unsigned long ulPriorityMask)
718 {
719     CPUbasepriSet(ulPriorityMask);
720 }
721 
722 //*****************************************************************************
723 //
724 //! Gets the priority masking level
725 //!
726 //! This function gets the current setting of the interrupt priority masking
727 //! level.  The value returned is the priority level such that all interrupts
728 //! of that and lesser priority are masked.  A value of 0 means that priority
729 //! masking is disabled.
730 //!
731 //! Smaller numbers correspond to higher interrupt priorities.  So for example
732 //! a priority level mask of 4 allows interrupts of priority level 0-3,
733 //! and interrupts with a numerical priority of 4 and greater are blocked.
734 //!
735 //! The hardware priority mechanism only looks at the upper N bits of the
736 //! priority level (where N is 3 for the Stellaris family), so any
737 //! prioritization must be performed in those bits.
738 //!
739 //! \return Returns the value of the interrupt priority level mask.
740 //
741 //*****************************************************************************
742 unsigned long
IntPriorityMaskGet(void)743 IntPriorityMaskGet(void)
744 {
745     return(CPUbasepriGet());
746 }
747 
748 //*****************************************************************************
749 //
750 // Close the Doxygen group.
751 //! @}
752 //
753 //*****************************************************************************
754